流读取:EOF与0计数的区别

4
Stream.Read 的文档指出:

只有当流中没有更多数据且不再需要更多数据(例如已关闭的套接字或文件结束)时,才会返回 0。

由此可见,即使将 0 传递给 count 参数,Read 也不应该返回 0。
但是,在使用 MemoryStream 进行测试时,它返回了 0。
var mem = new MemoryStream(new byte[] {1, 2, 3, 4});
var buf = new byte[0];
var ret = mem.Read(buf, 0, buf.Length);
Console.WriteLine(ret); // prints 0

这是否意味着文档缺少某些内容?
如果 count 为 0,一个实现是否可以抛出异常?


3
我猜是文档问题。我认为它应该是有效的,但使用计数为0调用该方法是没有意义的。 - Damien_The_Unbeliever
如果我没记错的话,备注部分不是文档正文的一部分(也就是说,并非合同行为的一部分)。它只是提供了一些指南和设计决策的解释等。还要注意“实现将阻塞,直到至少可以读取一个字节的数据”,这在你的情况下也是错误的。至于异常,任何实现都可以抛出任何想要的异常,但是一个行为良好的派生类会避免抛出基类未定义的异常(请注意,在调用站点处理的异常)。count == 0是一个有效的参数,因此一个好的实现不会抛出异常。 - Luaan
“很明显,即使传递0给count,Read方法也不应返回0” - 为什么?该方法返回小于或等于请求的任意数量。由于没有更少的数字 - 您将始终获得0或异常(例如TimeoutException)。正如@Luaan所指出的那样,这可以用于阻止,直到有可读取的内容而实际上并未从缓冲区读取单个字节。 - Sinatr
@Sinatr 是的,文档中的返回标签是正确的:读入缓冲区的总字节数。如果当前没有那么多字节可用,则此值可能小于请求的字节数,或者如果已到达流的末尾,则为零(0)。但是备注部分是不正确/令人困惑的,因为它说只有在没有更多数据和不再期望时才返回0(请注意“only”)。 - wingerse
哈哈,这是个有趣的问题,不过我有点同意。我认为在EOF的情况下返回“-1”会更好。 - Thariq Nugrohotomo
1
@ThariqNugrohotomo 嗯,如果它返回一个值,可以是“返回的字节数”或“流结束”,而不是一个普通的整数,那就更好了 :) 但考虑到情况,零并不是一个糟糕的选择 - 考虑你几乎总是在循环中从流中读取; 如果您错误地读取了计数为零,则会一直旋转永远。 零作为退出值更安全 :) - Luaan
1个回答

0

您请求了0个字节,因此Read函数只读取了零个字节。

输出为0,并且基于文档

返回值

已读取到缓冲区中的总字节数。如果当前没有那么多字节可用,则可以少于所请求的字节数,或者如果已到达流的末尾,则为零(0)。

在您的示例中,零表示“请求的字节数”。


2
但正如OP在他们的问题中强调的那样,文档说明仅当流的结尾已经到达时才返回0,而这显然是不正确的,因为随后的非零读取将返回更多字节。 - Damien_The_Unbeliever

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接