我有一个应用程序通过网络接收数据块,并将这些数据写入磁盘。一旦收到所有块,就可以将它们解码/重新组合成它们实际代表的单个文件。
我想知道使用内存映射文件是否有用 - 首先用于将单个块写入磁盘,其次用于将所有块都解码到的单个文件。
我自己的感觉是它可能只对第二种情况有用,有人对此有一些想法吗?
编辑:这是一个 C# 应用程序,我只计划一个 x64 版本。(因此遇到“最大的连续可用空间”问题不应该是相关的)
我有一个应用程序通过网络接收数据块,并将这些数据写入磁盘。一旦收到所有块,就可以将它们解码/重新组合成它们实际代表的单个文件。
我想知道使用内存映射文件是否有用 - 首先用于将单个块写入磁盘,其次用于将所有块都解码到的单个文件。
我自己的感觉是它可能只对第二种情况有用,有人对此有一些想法吗?
编辑:这是一个 C# 应用程序,我只计划一个 x64 版本。(因此遇到“最大的连续可用空间”问题不应该是相关的)
内存映射文件适用于需要重复访问相当大文件的相对较小部分(视图)的情况。
在这种情况下,操作系统可以通过只调入和调出映射文件中最近使用的部分来帮助优化应用程序的整体内存使用和分页行为。
此外,内存映射文件可以公开有趣的特性,例如写时复制或作为共享内存的基础。
对于您的场景,如果块乱序到达,内存映射文件可以帮助您组装文件。但是,您仍然需要提前知道最终文件的大小。
此外,您应该只访问一次文件,以写入一个块。因此,与显式实现的异步 I/O 相比,性能优势不太可能,但正确实现文件编写器可能更容易和更快。
在 .NET 4 中,Microsoft 添加了对内存映射文件的支持,并且有一些带有示例代码的综合文章,例如http://blogs.msdn.com/salvapatuel/archive/2009/06/08/working-with-memory-映射文件-in-net-4.aspx。
内存映射文件主要用于进程间通信或 I/O 性能改进。
就您而言,您是否试图获得更好的 I/O 性能?
讨厌指出显而易见的事情,但维基百科很好地概述了这种情况...... http://en.wikipedia.org/wiki/Memory-mapped_file
具体来说...
内存映射方法的代价是轻微的页面错误——当数据块加载到页面缓存中,但尚未映射到进程的虚拟内存空间时。根据具体情况,内存映射文件 I/O 实际上可能比标准文件 I/O 慢很多。
听起来您将过早地优化速度。为什么不采用常规文件方法,然后在需要时重构 MM 文件?
我想说这两种情况都是相关的。只需将单个块乱序写入内存映射文件中的适当位置,因为它们进入。这当然只有在您知道每个块应该去哪里时才有用,例如在 bittorrent 下载器中。如果您必须执行一些额外的分析才能知道块应该去哪里,那么内存映射文件的好处可能不会那么大。