结合FileStream和MemoryStream以避免磁盘访问/分页,同时接收千兆字节的数据?

w12*_*128 3 .net c# memory-management memorystream filestream

我收到一个文件作为byte []数据包流(总大小未提前知道),我需要在收到它之前立即处理它(我无法动态处理) ).收到的文件总大小可以从10 KB到4 GB不等.

  • 用于存储所接收数据的一个选项是使用a MemoryStream,即一系列MemoryStream.Write(bufferReceived, 0, count)调用来存储所接收的分组.这很简单,但显然会导致大文件的内存不足异常.
  • 另一种选择是使用a FileStream,即FileStream.Write(bufferReceived, 0, count).这样,不会出现内存不足异常,但我不确定的是由于磁盘写入导致的性能不佳(只要仍有大量内存可用,我不想发生) - 我想要尽可能避免磁盘访问,但我不知道如何控制它.

我做了一些测试,大部分时间,似乎在连续10次连续调用MemoryStream.Write()vs 之间几乎没有性能差异FileStream.Write(),但很多似乎取决于缓冲区大小和有问题的数据总量(即写入次数) .显然,MemoryStream尺寸重新分配也是一个因素.

  1. 默认情况下使用MemoryStreamFileStream,即写入内存流的组合是否有意义,但是一旦收到的数据总量超过例如500 MB,请将其写入FileStream; 然后,从两个流中读取块以处理接收到的数据(首先处理500 MB MemoryStream,处理它,然后读取FileStream)?

  2. 另一种解决方案是使用自定义内存流实现,该实现不需要连续的地址空间用于内部数组分配(即内存流的链接列表); 这样,至少在64位环境中,内存不足异常应该不再是问题.骗局:额外的工作,更多的错误空间.

那么FileStreamvs MemoryStream读/写如何在磁盘访问和内存缓存方面表现出来,即数据大小/性能平衡.我希望只要有足够的RAM可用,FileStream无论如何都会从内存(缓存)内部读/写,虚拟内存将负责其余的工作.但我不知道FileStream在写入磁盘时是否经常显式访问磁盘.

任何帮助,将不胜感激.

Han*_*ant 5

不,试图优化这一点没有任何意义.Windows本身已经缓存文件写入,它们由文件系统缓存缓冲.所以你的测试是准确的,MemoryStream.Write()和FileStream.Write()实际写入RAM并没有明显的性能差异.文件系统驱动程序懒惰地在后台将其写入磁盘.

用于文件系统缓存的RAM是在进程声称其RAM需要之后剩余的.通过使用MemoryStream,可以降低文件系统缓存的有效性.换句话说,你在没有利益的情况下换取另一个.实际上你的情况更糟,你使用了两倍的RAM.

没有帮助,这已经在操作系统内进行了大量优化.