11

BinaryReader の内部バッファリング戦略のため、ストリームに保存されているオフセットを読み取ってから、このオフセットでストリームを再配置してストリーミングを再開することが適切かどうかは不明です。

例として、次のコードは問題ありません。

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

   //Then resume reading the streaming
}

または、ストリームをシークする前に最初のバイナリ リーダーを閉じてから、2 番目のリーダーを再度開く必要がありますか?

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
}
4

3 に答える 3

11

BinaryReader はバッファーを使用しますが、値を変換するのに十分なバイトをベース ストリームから読み取るためだけに使用します。つまり、ReadInt32() は最初に 4 バイトをバッファリングし、ReadDecimal() は最初に 16 バイトをバッファリングします。ReadString() はよりトリッキーな方法ですが、対策もあります。文字列は、最初に文字列の長さを書き込む BinaryWriter によってファイルにエンコードされます。そのため、BinaryReader は、文字列を変換する前にバッファするバイト数を正確に認識します。

そのため、ReadXxx() メソッドの 1 つが戻った後、バッファーは常に空であり、BaseStream で Seek() を呼び出すことは問題ありません。また、Microsoft が Seek() メソッドをオーバーライドする必要がなかった理由もあります。

MSDN 記事の注意書きは適切です。Seek() 呼び出しの後に ReadXxx() メソッドを呼び出すと、その「オフセット」値を複数回読み取ることになります。しかし、それは完全に意図的だったと思います。

于 2013-10-02T12:54:13.807 に答える
4

常に安全であるとは限りません(場合によっては安全かもしれませんが)。

BinaryReader.BaseStream に関する Microsoft のドキュメントには、次のように明示的に記載されています。

読み取り中または BinaryReader の使用中に基になるストリームを使用すると、データの損失や破損が発生する可能性があります。たとえば、同じバイトが複数回読み取られたり、バイトがスキップされたり、文字の読み取りが予測不能になったりする可能性があります。

だから私はそれを避けます。

(興味深いことに、BinaryWriter.Seek()メソッドはありますが、ありませんBinaryReader.Seek()。)

于 2013-10-02T09:57:13.380 に答える
3

私の経験では、両方を同期的に使用していて、他のスレッドがストリームで何もしていない限り、完全に正常に動作します。

私は、バイナリ ファイル形式で動作するように作成したアプリケーションでこれを広範囲に行い、問題に遭遇したことはありません。

于 2013-10-02T10:35:23.693 に答える