代码之家  ›  专栏  ›  技术社区  ›  Bas Smit

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

  •  3
  • Bas Smit  · 技术社区  · 16 年前

    嘿,伙计们,我最近看到这个网页 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 回复  |  直到 16 年前
        1
  •  5
  •   Jon Skeet    16 年前

    嗯,我相信 MemoryStream 如果可以的话,将始终填充缓冲区-除非您从中派生了一些邪恶类。但据我所见,这并不能保证。这个 documentation 甚至包含警告:

    即使没有到达流的末尾,实现也可以返回比请求的字节数更少的字节。

    就我个人而言,我总是用防御性的方式来编码,除非它能制造出东西。 许多的 更容易的。你永远不知道什么时候会有人改变流的类型,也不会注意到发生了什么。

    通常用 内存流 不过,我希望所有字节同时出现:所以我调用 MemoryStream.ToArray . 如果有人将代码更改为不使用 内存流 ,它将无法编译为该成员的 内存流 .对于一般流,我使用一个实用方法,它从流中完全读取并返回一个字节数组。

        2
  •  1
  •   leppie    16 年前

    我想不出任何正常的原因 MemoryStream . 不受管理可能是另一回事。

    不管怎样, GetBuffer() ToArray() 命令总是很方便的。:)

        3
  •  0
  •   Noldorin    16 年前

    是的,您应该始终知道调用时从流中实际读取了多少字节 Read . roout的原因可能因流类型的不同而不同,但本质上,当您试图在流的末尾之外读取时,返回值将小于实际的缓冲区大小。

        4
  •  0
  •   M4N    16 年前

    这里是什么 MSDN 说:

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

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

    请注意术语“实现…”。