Laden...

MemoryStream staffeln

Letzter Beitrag vor 17 Jahren 3 Posts 1.426 Views
MemoryStream staffeln

Moin,

Ich habe mit einem meiner Programme ein kleines Problem. Ich will die Bytes einer Datei (binär) auslesen. Ich verwende dazu diese Funktion:

public static byte[] ReadFully(Stream stream)
        {
            byte[] buffer = new byte[32768];
            using (MemoryStream ms = new MemoryStream())
            {
                while (true)
                {
                    int read = stream.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                        return ms.ToArray();
                    ms.Write(buffer, 0, read);
                }
            }
        }

Dies funktioniert recht gut, wenn ich aber grosse (70MB und mehr) behandle bekomme ich OutOfMemory Exceptions. Daher wollte ich fragen ob irgendwer hier ne Idee hat wie ich das verhindern könnte.

Ich hätte mir da gedacht den Vorgang zu staffeln. Ich hätte mir das so ausgedacht:

Funktion liest bis 10MB -> in ByteArray -> MemoryStream wird geleert -> Funktion liest ab 10MB bis 20MB -> ByteArray -> MemoryStream leeren.

Da ich aber keine Ahnung habe ob man das so realisieren kann wollte ich nur mal hier fragen 😉

EDIT: Nach dem genaueren Analysieren des Codes fiel mir auf das der Buffer nur auf 32768 Bytes ausgelegt ist. Daher meine Fragen:

  1. Kann das die Fehlerquelle sein?
  2. Kann, durch erweitern des ByteArrays auf eine größere Einheit, das Problem behoben werden?

du hast deine Daten jetzt auch 2-3 mal im Speicher...

Ich weis jetzt nicht von welchem Typ stream ist.. aber die meisten haben funktionen wie readToEnd damit sparst dir schonmal 70MB für den Memory Stream.

Wenn das nicht funktionier würde ich mir an deiner Stelle mal das yield statement anschauen

Du nimmst als rückgabewert IEnumerable<byte> und liest deinen Stream byte für byte aus. und gibst jedes Byte mit yield return byteVariable zurück. <- meiner meinung nach das speichersparenste konzept. Aber ich weis nicht wie es mit der Performance aussieht.

Zu deinen Edits :

1: Nein ich denke nicht das 32K Bytes Array zu einer OutofMemory Exception füren da du davon ja nur einen anlegst und diesen immer wieder befüllst. Wir reden hier ja vom MB

2 : Ich denke da suchst du am falschen Platz.

  • Du hast die Daten eventuell komplett im Stream -> ich weis ja nicht was für ein Stream deswegen eventuell. -> 70 MB
  • Am schluss hast du die Daten komplett im MemoryStream -> 70 + 70 = 140 MB
  • Dann erzeugst du daraus ein Array 70 + 70 + 70 = 210 MB