[英]FileStream.Read() - bytes read
FileStream.Read()
返回读取的字节数,但是...除了到达文件末尾之外,是否还有其他情况,它将读取的字节数少于请求的字节数, 并且不会引发异常 ?
该文件说:
Read方法仅在到达流末尾后才返回零。 否则,Read在返回之前总是从流中读取至少一个字节。 如果在调用Read时流中没有可用数据,则该方法将阻塞,直到可以返回至少一个字节的数据为止。 即使未到达流的末尾,实现也可以自由返回少于请求的字节数。
但这并不能完全解释在什么情况下数据将不可用并导致方法阻塞,直到可以再次读取为止。 我的意思是,大多数数据不可用的情况不是应该强制例外吗?
在实际情况下,将读取的字节数与预期的字节数进行比较可能会有所不同(假设当我们提到预期的字节数时,我们已经在检查文件末尾)吗?
编辑:更多信息,我问这个的原因是因为我遇到了一些代码,其中开发人员几乎做了这样的事情:
bytesExpected = (remainingBytesInFile > 94208 ? 94208 : remainingBytesInFile
while (bytesRead < bytesExpected)
{
bytesRead += fileStream.Read(buffer, bytesRead, bytesExpected - bytesRead)
}
现在,我完全看不到有什么优势,如果它无法读取预期的字节数,我希望它会引发异常(请记住,已经考虑到有很多剩下要读取的字节)
这样的事情可能会有什么原因呢? 我确定我错过了一些东西
该文档适用于Stream.Read
,派生自FileStream
。 由于FileStream
是流,因此它应遵守流协定。 并非所有流都可以,但是除非您有充分的理由,否则应坚持这一点。
在典型的文件流中,到达文件末尾时,返回值只会小于count(这是检查文件末尾的一种非常简单的方法)。
但是,例如,在NetworkStream
,您将一直循环读取,直到该方法返回零-表示流结束。 文件流的工作原理相同-当Read
返回零时,您就位于文件末尾。
最重要的是, FileStream
不仅适用于您要考虑的文件,还适用于伪文件,例如标准输入/输出管道和COM端口(例如,尝试在PRN
上打开文件流)。 在这种情况下,您不会读取固定长度的文件,并且其行为与NetworkStream
相同。
最后,不要忘记FileStream
没有密封。 例如,对于您来说,实现虚拟文件系统是非常好的-如果您的虚拟文件系统不支持查找或检查文件的长度,那么也非常好。
编辑:
为了解决您的修改,这正是您应阅读任何流的方式。 没错。 如果流中没有其他要读取的内容,则Read
方法将仅返回0
,并且您知道流已结束。 唯一的事情是,似乎他尝试一次将其缓冲区填满,一个缓冲区-仅当您明确需要将文件划分94208字节并将该byte[]
传递到某个地方进行进一步处理时,这才有意义。
如果不是这种情况,则实际上不需要填充整个缓冲区-您只需继续读取(可能在另一面进行写入),直到Read
返回0
。 确实,实际上,默认情况下, 除非 FileStream
始终围绕管道句柄构建, 否则它将始终填充整个缓冲区-但这是有可能的,因此,只要您需要这些byte[]
,就不应该依赖“真实文件”行为。对于某些非流式的内容(例如,解析消息),这完全可以。 如果仅将流用作实际流,并且将数据流传输到其他位置,则它没有意义,实际上-您只需要while
即可读取文件。
您的期望仅适用于流从无延迟源读取数据的情况。 其他I / O源的运行速度可能很慢,这就是为什么Read
方法可能无法始终立即返回的原因。 这并不意味着存在错误(因此也不例外),而只是它必须等待数据到达。
例如:网络流,慢速磁盘上的文件流等。
(UPDATE,HDD示例)给出一个特定于文件的示例(由于您的案例是FileStream
,尽管Read
是在Stream
上定义的,所以所有实现都应满足要求):机械硬盘在不活动时进入“睡眠”状态(特别是在电池供电的设备上,请阅读笔记本电脑)。 旋转可能需要一秒钟左右的时间。 那不是IOException
,但是在读取任何数据之前,您的读取必须等待一秒钟。
简单的答案是,在FileStream上可能永远不会发生。 但是请记住,Read方法是从Stream继承的,Stream是许多其他流(如NetworkStream)的基础,在这种情况下,您可能无法按您的要求读取许多字节,因为它们尚未从网络接收到。
因此,就像文档中所说的那样,这完全取决于特定类型的流的实现-FileStream,NetworkStream等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.