Einen frisch initialisierten MemoryStream übergebe ich einem StreamWriter:
System.IO.MemoryStream myStream = new System.IO.MemoryStream();
StreamWriter writer = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(850));
In einer Schlaufe füge ich diesem writer mit WriteLine ständig neue Daten hinzu.
Wenn ich im Debugmodus mein myStream Objekt anschaue (nach dem abfüllen), dann habe ich da ein par tausend Einträge, dessen Wert ein ASCII-Wert ist . Nun sind aber die letzten par (weiss nicht vielleicht 100) Einträge im buffer mit dem Wert 0.
Ich vermute das kommt daher, dass mein stream eine dynamische grösse hat und dass der writer die grösse vom stream nicht immer um eins sondern um vielleicht 100 Einträge erweitert, sobald er merkt das der Platz nicht mehr reicht.
Ich kann mein stream durchgehen und nur die Einträge mit value == 0 rauslöschen. Ich frage mich aber ob es da nicht eine besser Variante gibt ... ?
Hallo bubblez,
ich glaube das ist nur eine Frage der Anzeige im Debugger. Wenn du den MemoryStream über seine Operationen benutzt, dann wirst du da keine Nullwerte bemerken. Deshalb musst du m.E. auch nicht löschen.
herbivore
Hm das wäre zufriedenstellend, ist aber nicht so.
Das Problem ist eben, dass ich den bytearray in der Datenbank speicher um daraus später eine Datei zu generieren. Diese Datei wird immer grösser, bei jedem lesen / speichern Zugriff, da ja eben jedesmal unnötige null-bytes angehängt werden.
Ich habe jetzt ein workaround gemacht, der mir zuerst den ganzen bytearray durchgeht und nur die bytes in die datenbank schreibt, welche ein value != 0 haben. Allerdings schätze ich, dass dies nicht gerade perfomant ist, bedenkt man, dass ein solcher bytearray schnell mal 100000 Einträge haben kann.
Du könntest mit einem Zeiger über das Byte-Array iterieren.Aber gibt es denn
ein Performance - Problem? Du weißt ja: "Premature optimization is the root of all evil!"
Gernot Melichar
Hallo bubblez,
MemoryStream ms = new MemoryStream ();
ms.Write (new byte [] { 0x01, 0x02, 0x03 }, 0, 3);
Console.WriteLine (ms.Capacity);
Console.WriteLine (ms.Length);
Console.WriteLine (ms.GetBuffer ().Length);
ok, du hast Recht. Der Puffer hat die Größe ms.Capacity, aber nur die ersten ms.Length-vielen Bytes sind relevant.
herbivore
poste mal ein wenig code (lauffähig) bubblez
Da kannst Du sicher was über die Länge machen
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Hallo zusammen,
dass der Memory-Stream erweitert wird ist klar. Dass er Überlänge hat, ist dann zu bemerken, wenn man den Memory-Stream sich selbst erweitern lässt. Am besten man schaut sich auch mal die überladenen Konstruktoren in der MSDN hierzu an. Dort ist auch vermerkt welcher Konstruktor dafür sorgt, dass der MS erweiterbar ist.
Ein besonderes Augenmerk sollte auf die eigenschaft SetLength gelegt werden, mit der man selbst bestimmen kann, wie groß die Erweiterung werden soll.
So kann man bevor man einen Stream-Teil hinzufügt, genau um dessen Länge erweitern, und man hat keinen Byte verschenkt 😉
Relevante Links hierzu:
MSDN - MemoryStream.SetLength Eigenschaft
MSDN - MemoryStreams Constructors
Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
Hallo norman_timo,
So kann man bevor man einen Stream-Teil hinzufügt, genau um dessen Länge erweitern, und man hat keinen Byte verschenkt 😉
Das könnte der Performancetod sein. Vermutlich werden bei jeder Erweiterung des Streams, alle bisher geschrieben Daten kopiert.
Es könnte aber klappen, am Ende einmal ms.SetLength (ms.Length) aufzurufen (ungetestet).
herbivore
Hallo Herbivore,
ja stimmt, an so etwas habe ich nicht gedacht. Aber so wie Du schon sagtest, dann muss man halt vorher zählen, und die Streamlänge dann einmal initial setzen.
Ciao
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”