Frage

Ich habe einen TCP-Server in C # geschrieben bekam, die ihm geschickt POST Daten verarbeitet. Derzeit funktioniert es gut, wenn nicht eine große Menge von Daten (das heißt mehr als 1 GB) an ihn gesendet wird, dann läuft es aus dem Speicher (I es speichere alle im Speicher als ein Array von Bytes (mit Zwischenschaltung einer Liste DTO)). Für große Dateien streamen nach unten ich jetzt auf der Festplatte und dann die Dateinamen übergeben, um mit der Absicht, das Streaming von der Festplatte.

Zur Zeit alle meine Routinen geschrieben Byte-Arrays zu erwarten, die im Nachhinein war etwas kurzsichtig. Wenn ich nur die bytearray zu einem Memorystream konvertiert es die Speicherauslastung verdoppeln? Ich denke, das Neuschreiben meinen Code auf einem Memory arbeiten wird mir erlauben, es wieder zu verwenden, wenn ich einen Strom von der Festplatte gerade lese?

Sorry für die dummen Fragen, sie ist nie sicher, wenn c # eine Kopie der Daten erfolgt oder wenn es dauert eine Referenz.

War es hilfreich?

Lösung

Wenn Sie eine byte[] in eine MemoryStream passieren, dann wird es die Daten zunächst kopieren (im Konstruktor), aber solange man die byte[] freigeben kann es sein, Müll gesammelt. Von Natur aus gibt es keine „Verdoppelung“ (vor allem, wenn Sie die Größe festlegen können richtig mit zu beginnen, und schreiben Sie direkt an die Stream statt dem byte[]).

ich ganz Schalter Stream sagen würde (aber nur Verwendung Stream in der API - nichts moer spezifisch; Ihr raubend Code braucht nicht zu wissen, welche Art). Am wichtigsten ist, können Sie die NetworkStream verwenden (lesen direkt aus der Steckdose) oder FileStream (wenn Sie auf die Festplatte puffern wollen) oder MemoryStream, wenn Sie in-Prozess puffern wollen. Sie müssen auch sicherstellen, dass Sie diese Datenmenge über den Strom-basierten Code lesen. Iterator Blöcke (yield return) kann hier sehr hilfreich sein, ebenso wie die LINQ Enumerable Methoden (mit Ausnahme von OrderBy, GroupBy, usw., die Puffer).

Weder ein byte[] vorbei noch Leiten einen Stream verursacht etwas kopiert werden, da sie Referenztypen sind -. Das einzige, was kopiert ist die Referenz (4 oder 8 Bytes, abhängig von x86 / x64)

Andere Tipps

Ein Memorystream ist nur ein Stream-Wrapper um eine Byte-Array, so dass Sie nicht alles sein werden, zu gewinnen, indem Sie es.

Was Sie (für große Dateien mindestens) tun müssen, ist offen ein Filestream und Dump Ihre Daten in das. Auf einer niedrigeren Ebene Sie haben X Bytes von Ihrem Anschluss zu lesen und dann schreiben, dass sofort auf Ihre Datei-Stream. Auf diese Weise werden Sie nicht in einem vollen Gig in dem Speicher Strang ziehen, aber nur ein paar Bytes auf einmal.

Ob dies leicht sein wird zu tun, hängt davon ab, wie Sie Ihren TCP-Server codiert.

Da ein Byte ein Werttyp ist, wenn Sie es auf eine Funktion ohne Schlüsselwort ref übergeben Sie jedes Mal mit einer Kopie zu tun werden. Wenn Sie es mit dem Schlüsselwort ref passieren, wird es einen Verweis auf den ursprünglichen Byte-Array nehmen.

Ein Memorystream ist ein Referenztyp, so dass es nicht auf die Daten kopiert werden, aber Sie sind auf diese Daten um eine Referenz vorbei, so dass Ihre Speichernutzung bei der Verwendung das nicht verdoppeln wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top