当BinaryReader打开时使用Stream.Seek是否安全?

时间:2013-10-02 09:49:20

标签: c# stream binaryreader

由于BinaryReader的底层缓冲策略,我不清楚是否可以读取存储在流中的偏移量,然后在此偏移处重新定位流以恢复流式传输。

举个例子,下面的代码是好的:

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

   //Then resume reading the streaming
}

或者我应该在寻找流之前关闭第一个二进制阅读器,然后重新打开第二个阅读器?

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
}

3 个答案:

答案 0 :(得分:10)

BinaryReader确实使用缓冲区但从基本流中读取足够的字节以转换值。换句话说,ReadInt32()将首先缓冲4个字节,ReadDecimal()将首先缓冲16个字节,等等。 ReadString()是一种比较棘手的方法,但它也有反措施,BinaryWriter在文件中对字符串进行编码,首先写入字符串长度。这样BinaryReader就可以确切地知道在转换字符串之前要缓冲多少字节。

因此,在其中一个ReadXxx()方法返回并且在BaseStream上调用Seek()之后,缓冲区始终为空。也是微软不需要覆盖Seek()方法的原因。

MSDN文章中的注意事项是合适的,如果在Seek()调用之后调用ReadXxx()方法,您肯定会多次读取“offset”值。但我认为这完全是故意的。

答案 1 :(得分:3)

我会说 始终是安全的(虽然在某些情况下它可能是安全的)。

The Microsoft documentation for BinaryReader.BaseStream明确指出:

在读取时或使用BinaryReader时使用基础流可能会导致数据丢失和损坏。例如,可能会多次读取相同的字节,可能会跳过字节,或者字符读取可能变得不可预测。

所以我会避免它。

(有趣的是,有一个BinaryWriter.Seek()方法,但没有BinaryReader.Seek()。)

答案 2 :(得分:3)

根据我的经验,只要您同时使用它们,并且没有其他线程对流做任何事情,那么它的工作完全正常。

我在使用二进制文件格式编写的应用程序中广泛使用,并且从未遇到过问题。