FileStream.ReadByte - 低效 - 这是什么意思?

时间:2010-10-22 14:55:02

标签: .net performance filestream

  
    

Stream上的默认实现创建一个新的单字节数组,然后调用Read。虽然这是正式的,但效率低下。任何具有内部缓冲区的流都应该重写此方法,并提供一个更高效的版本,直接读取缓冲区,避免每次调用时额外的数组分配。

  

取自FileStream.ReadByte文档:

http://msdn.microsoft.com/en-us/library/system.io.filestream.readbyte.aspx

这是什么,以及如何克服这种低效率?

5 个答案:

答案 0 :(得分:4)

嗯,意思似乎相当清楚 - 解决方法就是不要拨打ReadByte

不要一次读取一个字节 - 使用Read(byte[], int, int)方法读入适当大小的缓冲区(我通常大约8K,但大约那个数量级的任何东西应该没问题)。如果您需要在此之后单独读取字节,请从缓冲区中一次读取一个。

如果您需要确保读取的内容超出了您的意图,如果您看到我的意思,那么这就成了一个问题 - 例如,如果您不打算读取前0个字节,因为这意味着它是下一个“消息”的开始,并且您希望以后能够再次阅读。理想情况下,避免将自己设计成这种情况。

在这种情况下,

FileStream 中包含BufferedStream可能有所帮助,但如果重要的话,我会仔细衡量一下这些表现......并且仍然会尽量避免设计如果你能提供帮助,则需要一次读取一个字节。

答案 1 :(得分:3)

您需要使用Read方法来读取缓冲区。读单字节效率不高。使用缓冲区:

  byte[] buffer = new byte[4096]; // 4K
  int bytesRead =0;
  while((bytesRead = stream.Read(buffer, 0, buffer.Length))>0)
  {
  // Do whatever with buffer
  }

答案 2 :(得分:3)

当您从Stream继承时,这只是一个值得关注的问题。执行此操作时,您必须至少提供Read方法,ReadByte在基类中实现。ReadByte。这很好,但是当你的流能够直接获取单个字节时效率很低 - 默认实现将首先在内部创建一个单字节缓冲区,将其传递给Read以填充它,然后返回单个字节。如果你可以实现你的缓冲区,以便可以直接返回单个字节,而不需要分配临时缓冲区,你应该这样做。

对于调用代码,唯一的考虑因素是,当您需要读取字节只是为了将它们存储在缓冲区中时,ReadByte通常比ReadByte更有效,即使您只是在阅读单个字节 - 但如果您真的只需要一个字节,并且您使用的流实现提供了优化版本,ReadByte实际上可能更快。如果您读取单个字节以便立即处理,ReadByte根本不应该成为问题 - 毕竟,大多数标准流类已经缓冲,应该提供优化的{{1}}。如有疑问,请参阅。

答案 3 :(得分:2)

我在使用FileStream ReadByte()方法时未发现任何问题。

我认为文档实际上令人困惑。

抽象Stream类实现的ReadByte()方法效率低下,因为它"创建一个新的单字节数组,然后调用Read()"。

但是,由FileStream实现的ReadByte()的重写版本通过直接读取内部缓冲区来听取此警告的建议,如您在源here中看到的那样。因此,我们不清楚为什么FileStream ReadByte()的文档会对此警告产生影响。

答案 4 :(得分:1)

我会读到这是一种写得很差的方式来说“不要使用ReadByte()并使用Read()代替”。特别是因为Read()的文档说明了

  

此方法会覆盖Read。

<备注部分中的