如果我正在读取的字节还不存在,BinaryReader 会做啥?
Posted
技术标签:
【中文标题】如果我正在读取的字节还不存在,BinaryReader 会做啥?【英文标题】:What does BinaryReader do if the bytes I am reading aren't present yet?如果我正在读取的字节还不存在,BinaryReader 会做什么? 【发布时间】:2012-06-04 08:17:31 【问题描述】:我在 NetworkStream 之上使用 BinaryReader 从网络中读取数据。这对我来说非常有效,但我想了解幕后发生的事情,所以我查看了 BinaryReader 的文档,发现它非常稀疏。
我的问题是:当我调用ReadBytes
时,如果网络流中没有bufferSize
字节,BinaryReader.ReadBytes(bufferSize)
会做什么?
在我看来,有几个选择:
1) 读取网络流中存在的任何字节并仅返回那么多
2) 等到流中出现bufferSize
字节,然后读取
3) 抛出异常
我假设选项 2 正在发生,因为我从未收到任何异常,并且我的所有数据都是完整接收的,而不是分段接收的。但是,我想确切地知道发生了什么。如果有人能启发我,我将不胜感激。
【问题讨论】:
它将阻止并确保您获得请求的字节数。如果流已关闭并且您已全部阅读,您只会获得更少。 【参考方案1】:我相信它实际上适用于隐藏选项 4:
在数据可用时读取数据,以与通常手动执行相同的方式循环。如果它在读取时到达流的end,它只会返回一个小于您要求的字节数的值。这与您的选项 2 略有不同,因为它确实在数据可用时耗尽流 - 它不会等到它可以一次性读取所有数据。
很容易证明,如果它到达末尾,它返回的字节数确实比您要求的要少:
var ms = new MemoryStream(new byte[10]);
var readData = new BinaryReader(ms).ReadBytes(100);
Console.WriteLine(readData.Length); // 10
如果没有自定义流,则更难证明循环部分。需要多次Read
调用以返回所有数据。
文档不是很清楚,但返回值部分至少有点有帮助:
一个字节数组,包含从底层流中读取的数据。 如果到达流的末尾,这可能小于请求的字节数。
注意我突出显示的最后一部分,并将其与Stream.Read
进行比较:
读入缓冲区的总字节数。这可能小于请求的字节数如果当前没有那么多字节可用,或者如果已到达流的末尾则为零 (0)。
如果您希望获得准确的数据量并且仅该数量会有用,我建议您编写一个 ReadExactly
方法,该方法调用 Read
并在需要时抛出 EndOfStreamException
比关闭之前提供的流更多的数据。
【讨论】:
感谢您在回复中提供的详细信息。不过,我确实有一个快速、简单的问题。只有在流关闭时才能到达流的末尾,对吗?【参考方案2】:如果,通过“出现在流上”,您是在询问该方法是否会阻塞,直到指定的字节数可用,那么它是选项 2。如果 已到达流的结尾。
下面是一些关于如何实现BinaryReader.ReadBytes(int)
的示例代码:
byte[] ReadBytes(int count)
byte[] buffer = new byte[count];
int total = 0;
int read = 0;
do
read = stream.Read(buffer, read, count - total);
total += read;
while (read > 0 && total < count);
// Resize buffer if smaller than count (code not shown).
return buffer;
【讨论】:
以上是关于如果我正在读取的字节还不存在,BinaryReader 会做啥?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Python 通过 Serial 读取不固定数量的字节
关于处理iis8.0中设置Request.BinaryRead 不允许操作的解决方法