嘿伙计们,我最近遇到了这个网页http://www.yoda.arachsys.com/csharp/readbinary.html,解释了从文件流中读取时要采取的预防措施。它的要点是以下代码并不总是有效:
// Bad code! Do not use!
FileStream fs = File.OpenRead(filename);
byte[] data = new byte[fs.Length];
fs.Read (data, 0, data.Length);
这很危险,因为Read的第三个参数是要读取的最大字节,你应该使用Read的返回值来检查实际读取的数量。
我的问题是,在读取内存流时是否应采取相同的预防措施,以及在读取所有字节之前可能会在哪些情况下返回读取?
谢谢,Bas
答案 0 :(得分:5)
嗯,我相信MemoryStream
的当前实现将始终填充缓冲区,如果可以的话 - 除非你有一些派生自它的邪恶类。据我所知,这并不能保证。 documentation甚至包含警告:
即使尚未到达流的末尾,实现也可以自由返回少于请求的字节数。
就个人而言,我总是在防守方面进行编码,除非它使更多更容易。你永远不知道什么时候有人会改变流的类型,而不会注意到发生了什么。
通常使用MemoryStream
,我想同时拥有所有字节:所以我调用MemoryStream.ToArray
。这保证可以正常工作,如果有人将代码更改为不使用MemoryStream
,则无法仅在MemoryStream
上编译该成员。对于一般流,我使用一个实用程序方法,它从流中完全读取并返回一个字节数组。
答案 1 :(得分:1)
我无法想出正常MemoryStream
的任何原因。未管理的可能是另一回事。
无论如何, GetBuffer()
ToArray()
命令总是很方便。 :)
答案 2 :(得分:0)
是的,您应该始终了解在调用Read
时实际从流中读取了多少字节。 roout原因可能因流类型而异,但是当您尝试读取流的末尾时,返回值实际上将小于实际缓冲区大小。
答案 3 :(得分:0)
以下是MSDN所说的内容:
...可以小于数量 请求的字节数 字节当前不可用,或 如果流的结尾是零 在读取任何字节之前达到。
和
实施可以自由返回 字节数少于请求的字节数 流的结尾还没有 达到。
注意术语“实施......”。