如何在Windows 7下有限RAM的计算机上读取大文件?文件大小为25GB,但RAM容量仅为16GB

时间:2014-07-15 05:21:15

标签: c++ windows unmanaged filesize

我需要开发一个应用程序来读取包含俄罗斯高速公路图的文件。在文件内容的基础上,应用程序必须检测两个指定城镇之间的最短路径。应用程序必须用C ++中的非托管代码编写。我需要在MS VS 2013中开发此应用程序作为C ++控制台应用程序而不支持MFC。客户计算机上有一个Windows 7操作系统。作为搜索引擎 - 必须使用“A *”算法。我的问题如下。包含高速公路图的文件大小为25GB,但客户计算机上的RAM容量仅为16GB,没有机会扩展它。是否有任何非托管C ++编程技术可用于处理大文件?我想到的是,读取文件的大小大于计算机上的RAM容量。在这种情况下我应该以什么方式设计应用程序架构?

5 个答案:

答案 0 :(得分:2)

您必须在文件句柄上调用 CreateFileMapping ,然后在映射句柄上调用 MapViewOfFile 。它非常方便,允许您在不读取文件的情况下访问整个文件。在这种情况下,您的目标必须 64位 ...

答案 1 :(得分:1)

使用std::readline,您可以一次读取一行文件。 640 kB RAM就够了;)

我很确定它是一个文本文件,甚至可能是XML。在这种情况下,您将使用专用的" SAX" XML解析器。我知道它不是二进制的,因为我知道你可以在8 GB以下的地方适应整个欧洲地图(高速公路和所有小路)。

顺便说一下,A *已经过时了。现代路由算法(如ArcFlags)要快得多。

答案 2 :(得分:0)

嗯...为什么不只是按小部分阅读文件?可以说,来自文件的128条记录。 你可以创建一些隐藏在这个机制中的类,因此程序的其他部分不承认完全加载和这个方法之间的区别。 其他方式 - 将文件映射到内存。

不,你来自俄罗斯吗?

答案 3 :(得分:0)

你的问题很广泛!您面临的主要问题是加载/卸载数据块会使您的搜索极其缓慢,尤其是在相邻节点处于不同块的情况下。

由于你的图表是真实世界的地理位置,你的A *启发式肯定会是数学距离btw点。这意味着您的算法将主要基于到目标的距离来开发路径,您可以使用它来优化加载/卸载:

这里有一些提示:

  • 如果您可以按地理方块对数据进行分组来整理数据文件,那么至少可以减少一点加载/卸载成本。

  • 想到每个方块的fil偏移的内存中索引,以便您可以更快地访问要加载的新块。

  • 您也可以将此方法与缓存结合使用。而不是将大方块加载到一个最大大小的块中,更好地将较小的方块加载到几个较小的内存块中,您使用缓存算法管理(最近最少使用的是卸载):由于不需要许多地理区域,它们将被最常替换使用的节点(即高速公路周围的节点)。

  • 虽然有点创造力,但你可能也会略微偏离标准A *,加上一点点"光束":而不是总是采取最佳的扩展路径,考虑到它有时可以更有效地扩展保留在同一内存块中的路径。

答案 4 :(得分:0)

不确定这是否仍然是一个悬而未决的问题,只是看到了这个问题。

32位应用程序完全能够读取/写入文件> 4GB。

您甚至不需要为它创建文件映射,除非您绝对必须拥有(相当于)数据的内存中表示。如果是这种情况,那将会有更多工作但仍然可行(您可以创建一个类来包装文件的映射视图,并将数据“分块”为适合您可用地址空间的大小)。如其他人所述,您无法同时映射大于地址空间的文件。此外,以前关于性能考虑的答案/评论中的评论和警告将适用。

几个问题:文件如何编入索引(如果是)?你可以发布一个索引布局的例子和一个记录,如果它有一个索引?即使没有编入索引,您也可以通过包装器类创建自己的索引和访问记录。你能发布个人记录的例子吗?

如果你不需要内存中的表示,一个更好的选择 - 当然从性能的角度来看 - 就是创建一个处理文件读取/写入的类,并使用SetFilePointerEx来寻找任何读物。如果文件具有适合可见地址空间的索引,您甚至可以将该文件的该部分映射到内存中,并根据需要对各个记录(未映射)进行搜索/读取。更复杂的方法还可以处理MRU(或其他)基础上的缓存记录,以帮助提高性能。