Stream.Read何时返回?

时间:2014-02-18 10:24:59

标签: c# stream .net

考虑这个简单的代码:

    public void TransferStream(Stream source, Stream target)
    {
        Int32 read = -1;
        Byte[] buffer = new Byte[4096];
        do
        {
            read = source.Read(buffer, 0, buffer.Length);
            target.Write(buffer, 0, read);
        }
        while (read != 0);
    }

想象一下sourceNetworkStream,信息一点一点地到来。 source.Read可以使用完整缓冲区返回,或者使用部分缓冲区返回,read将告知读取了多少。

如果没有足够的数据填充缓冲区,source.Read何时返回?什么时候用部分缓冲区返回就足够了?

1 个答案:

答案 0 :(得分:2)

The documentation for `Stream.Read()'州:

  

此方法的实现从中读取最大计数字节数   当前流并将它们存储在从offset开始的缓冲区中。该   流中的当前位置按字节数提前   读;但是,如果发生异常,则当前位置在   流保持不变。

     

实现返回字节数   读。 实现将阻塞至少一个字节的数据   如果没有可用的数据,可以阅读。读取返回0   只有当流中没有更多数据且预计不再有数据时   (例如封闭的套接字或文件末尾)。实现是免费的   返回的字节数少于请求的字节数,即使流的末尾有   没有达到。

因此,根据这一点,NetworkStream 阻塞,直到它关闭或至少有一个字节可用。它实际上是否真的是另一回事 - 但我希望它能做到。

肯定会返回部分缓冲区。

然而更一般地说,我确实在过去发现,如果您在共享模式下打开了一个文件,而在您正在阅读该文件时其他内容正在写入该文件,那么即使File.Read()也可以返回零数据仍在写入(并且后续读取返回非零) - 所以要注意这种事情。我认为NetworkStream不会遇到这个问题。尽管如此,编写一个测试程序来确定这一点可能是一个好主意!

[编辑]

我查看了它的源代码,最终最终调用了Windows API recv()函数。我知道可以返回部分缓冲区,因此我们必须假设NetworkStream.Read()也可以返回部分缓冲区。