考虑这个简单的代码:
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
何时返回?什么时候用部分缓冲区返回就足够了?
答案 0 :(得分:2)
The documentation for `Stream.Read()'州:
此方法的实现从中读取最大计数字节数 当前流并将它们存储在从offset开始的缓冲区中。该 流中的当前位置按字节数提前 读;但是,如果发生异常,则当前位置在 流保持不变。
实现返回字节数 读。 实现将阻塞至少一个字节的数据 如果没有可用的数据,可以阅读。读取返回0 只有当流中没有更多数据且预计不再有数据时 (例如封闭的套接字或文件末尾)。实现是免费的 返回的字节数少于请求的字节数,即使流的末尾有 没有达到。
因此,根据这一点,NetworkStream 应阻塞,直到它关闭或至少有一个字节可用。它实际上是否真的是另一回事 - 但我希望它能做到。
它肯定会返回部分缓冲区。
然而更一般地说,我确实在过去发现,如果您在共享模式下打开了一个文件,而在您正在阅读该文件时其他内容正在写入该文件,那么即使File.Read()
也可以返回零数据仍在写入(并且后续读取返回非零) - 所以要注意这种事情。我认为NetworkStream
不会遇到这个问题。尽管如此,编写一个测试程序来确定这一点可能是一个好主意!
[编辑]
我查看了它的源代码,最终最终调用了Windows API recv()
函数。我知道可以返回部分缓冲区,因此我们必须假设NetworkStream.Read()
也可以返回部分缓冲区。