在c#中从内存流中读取的注意事项

时间:2009-09-18 15:11:14

标签: c# memorystream

嘿伙计们,我最近遇到了这个网页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

4 个答案:

答案 0 :(得分:5)

嗯,我相信MemoryStream的当前实现将始终填充缓冲区,如果可以的话 - 除非你有一些派生自它的邪恶类。据我所知,这并不能保证。 documentation甚至包含警告:

  

即使尚未到达流的末尾,实现也可以自由返回少于请求的字节数。

就个人而言,我总是在防守方面进行编码,除非它使更多更容易。你永远不知道什么时候有人会改变流的类型,而不会注意到发生了什么。

通常使用MemoryStream,我想同时拥有所有字节:所以我调用MemoryStream.ToArray。这保证可以正常工作,如果有人将代码更改为不使用MemoryStream,则无法仅在MemoryStream上编译该成员。对于一般流,我使用一个实用程序方法,它从流中完全读取并返回一个字节数组。

答案 1 :(得分:1)

我无法想出正常MemoryStream的任何原因。未管理的可能是另一回事。

无论如何, GetBuffer() ToArray()命令总是很方便。 :)

答案 2 :(得分:0)

是的,您应该始终了解在调用Read时实际从流中读取了多少字节。 roout原因可能因流类型而异,但是当您尝试读取流的末尾时,返回值实际上将小于实际缓冲区大小。

答案 3 :(得分:0)

以下是MSDN所说的内容:

  

...可以小于数量   请求的字节数   字节当前不可用,或   如果流的结尾是零   在读取任何字节之前达到。

  

实施可以自由返回   字节数少于请求的字节数   流的结尾还没有   达到。

注意术语“实施......”。