考虑一下这个简单的代码:
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);
}
假设source
是NetworkStream
,并且信息正在一点一点地到达。source.Read
可以返回一个完整的缓冲区,或者返回一个部分缓冲区,read
将告知读取了多少。
如果没有足够的数据来填充缓冲区,source.Read
什么时候返回?什么时候返回部分缓冲区就足够了?
"Stream.Read()"的文档说明:
此方法的实现从当前流,并从偏移量开始将它们存储在缓冲区中。这个流中的当前位置提前了字节数阅读但是,如果发生异常,则流保持不变。
实现返回字节数阅读实现将阻塞,直到至少有一个字节的数据在没有可用数据的情况下,可以读取。读取返回0仅当流中没有更多数据并且预期不会有更多数据时(例如闭合的套接字或文件末尾)。实现是免费的即使流的末尾有未联系到。
因此,NetworkStream应该阻塞,直到它关闭或至少有一个字节可用。它是否真的会是另一回事,但我希望它会。
它可以肯定地返回部分缓冲区。
然而,更普遍的是,我在过去确实发现,如果你在共享模式下打开了一个文件,并且在你从中读取时有其他东西正在向该文件写入,那么即使数据仍在写入,File.Read()
也可以返回零(随后的读取返回非零),所以要注意这种情况。不过,我认为NetworkStream
不会遇到这个问题。尽管如此,编写一个测试程序来确定这一点可能是个好主意!
[编辑]
我查看了它的源代码,最终它调用了Windowsneneneba APIrecv()
函数。我知道它可以返回部分缓冲区,所以我们必须假设NetworkStream.Read()
也可以返回部分缓冲器。