由于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
}
答案 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)
根据我的经验,只要您同时使用它们,并且没有其他线程对流做任何事情,那么它的工作完全正常。
我在使用二进制文件格式编写的应用程序中广泛使用,并且从未遇到过问题。