如果我正在读取的字节不存在,BinaryReader会怎么做?

时间:2012-05-30 05:31:10

标签: c# .net networking binaryreader

我在NetworkStream之上使用BinaryReader来读取网络上的数据。这对我来说非常有用,但我想了解幕后发生了什么,所以我看了一下BinaryReader的文档,发现它非常稀疏。

我的问题是:当我呼叫BinaryReader.ReadBytes(bufferSize)时,如果bufferSize字节在网络流中不存在,ReadBytes会做什么?

在我看来,有几个选择:
1)读取网络流上存在的任何字节,只返回那么多的字节 2)等到流上出现bufferSize字节,然后读取
3)抛出异常

我认为选项2正在发生,因为我从未收到过任何例外情况,而且我的所有数据都是全部收到的,而不是分成几部分。但是,我想知道发生了什么。如果有人能够启发我,我将不胜感激。

2 个答案:

答案 0 :(得分:10)

我相信实际用于隐藏选项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并抛出{{ 1}}如果您需要的数据多于关闭之前提供的流。

答案 1 :(得分:0)

如果,通过“当前在流上”,您询问该方法是否会阻塞,直到指定的字节数可用,那么它是选项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;
}