2013-10-02 12 views
5

Aufgrund der unter der Haube-Pufferungsstrategie von BinaryReader ist es mir unklar, ob es in Ordnung ist oder nicht, einen in einem Stream gespeicherten Offset zu lesen, dann den Stream an diesem Offset neu positionieren, um das Streaming fortzusetzen.Ist es sicher, Stream.Seek zu verwenden, wenn ein BinaryReader geöffnet ist?

Als Beispiel ist der folgende Code ok:

using (var reader = new CustomBinaryReader(inputStream)) 
{ 
    var offset= reader.ReadInt32(); 
    reader.BaseStream.Seek(offset, SeekOrigin.Begin); 

    //Then resume reading the streaming 
} 

Oder sollte ich das erste binäre Leser schließen, bevor der Strom Sucht und dann einen zweiten Leser wieder öffnen?

int offset; 
using (var firstReader = new CustomBinaryReader(inputStream)) 
{ 
    offset= firstReader.ReadInt32(); 
} 
inputStream.Seek(offset, SeekOrigin.Begin); 
using (var secondReader = new CustomBinaryReader(inputStream)) 
{ 
    //Then resume reading the streaming 
} 

Antwort

9

BinaryReader verwendet einen Puffer aber nur, um genügend Bytes aus dem Basisstream zu lesen, um einen Wert zu konvertieren. Mit anderen Worten, ReadInt32() puffert zuerst 4 Bytes, ReadDecimal() puffert zuerst 16 Bytes und so weiter. ReadString() ist die schwierigere Methode, aber es hat auch Gegenmaßnahmen, eine Zeichenfolge wird in der Datei von BinaryWriter codiert, die die Zeichenfolge Länge zuerst schreibt. Damit kann BinaryReader vor dem Konvertieren der Zeichenfolge genau wissen, wie viele Bytes gepuffert werden sollen.

Also der Puffer ist immer leer, nachdem eine der ReadXxx() -Methode zurückkehrt und Aufruf von Seek() auf dem BaseStream in Ordnung ist. Auch der Grund, dass Microsoft die Seek() - Methode nicht überschreiben musste.

Die Vorsichtshinweis im MSDN-Artikel ist geeignet, Sie sicherlich werden lesen, dass "Offset" Wert mehr als einmal, wenn Sie eine ReadXxx() -Methode nach dem Seek() aufrufen aufrufen. Ich gehe jedoch davon aus, dass dies ausschließlich beabsichtigt war.

+2

Hans, warum würden Sie den Offset-Wert mehr als einmal lesen, wenn Sie nach dem Seek() - Aufruf eine ReadXxx() -Methode aufrufen? Wird der BinaryReader den Puffer nicht einfach auffüllen und Ihnen die richtigen Werte geben? Es sei denn natürlich, der Offset hat einen Wert, der dem Ort des geschriebenen Offset selbst entspricht - dann landen Sie genau dort, wo Sie angefangen haben. – BKewl

2

Ich würde sagen, dass es nicht immer sicher ist (obwohl es vielleicht in einigen Fällen sicher sein).

The Microsoft documentation for BinaryReader.BaseStream heißt es ausdrücklich:

die zugrunde liegenden Stream Verwendung beim Lesen oder bei der Verwendung der Binary kann zu Datenverlust und Korruption führen. Zum Beispiel könnten dieselben Bytes mehr als einmal gelesen werden, Bytes könnten übersprungen werden, oder das Lesen von Zeichen könnte unvorhersehbar werden.

So würde ich es vermeiden.

(Interessanterweise gibt es eine BinaryWriter.Seek() Methode, aber keine BinaryReader.Seek().)

2

Nach meiner Erfahrung so lange, wie Sie sie beide synchron und kein anderer Thread verwenden, ist mit dem Strom etwas zu tun, dann ist es völlig in Ordnung, funktioniert.

Ich mache das ausgiebig in Anwendungen, die ich geschrieben habe, um mit binären Dateiformaten zu arbeiten und habe noch nie ein Problem festgestellt.