如何在windows7有限内存的电脑上读取大文件?文件大小为25GB,但RAM容量只有16GB



我需要开发一个应用程序,读取包含俄罗斯高速公路图形的文件。基于文件的内容,应用程序必须检测两个指定城镇之间的最短路由。应用程序必须用c++的非托管代码编写。我需要在MS VS 2013中开发此应用程序作为没有MFC支持的c++控制台应用程序。客户的电脑安装了Windows 7操作系统。作为搜索引擎-"a *"算法必须使用。我的问题如下。包含高速公路图形的文件大小为25GB,但客户计算机的RAM容量只有16GB,无法扩展。在这种情况下,我可以使用非托管c++的编程技术来处理大文件吗?我想在这种情况下,读取文件的大小大于计算机上的RAM容量。在这种情况下,我应该以何种方式设计应用程序体系结构?

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

使用std::readline,您可以一次一行地读取文件。640kb内存就足够了;)

我很确定这是一个文本文件,甚至可能是XML。在这种情况下,您将使用专用的"SAX"XML解析器。我知道这不是二进制的,因为我知道你可以把整个欧洲地图(包括高速公路和所有次要道路)压缩到8gb以下。

顺便说一句,A*已经过时了。像ArcFlags这样的现代路由算法要快得多。

嗯…为什么不按一小部分读取文件呢?比方说,从文件中删除128条记录。您可以创建一些类,这些类将隐藏在此机制中,因此程序的其他部分不会承认完全加载和此方法之间的区别。其他方式-将文件映射到内存。

顺便说一句,你是俄罗斯人吗?

你的问题很广泛!您将面临的主要问题是加载/卸载数据块会使您的搜索非常缓慢,特别是当相邻节点位于不同块中时。

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

这里有一些提示:

  • 如果你能将数据按地理方块分组来组织你的数据文件,你至少可以减少一点加载/卸载成本。

  • 考虑每个正方形的文件偏移量的内存索引,以便您可以更快地访问要加载的新块。

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

  • 只要有一点创意,你也许还可以稍微偏离标准a *,通过添加一点"光束":与其总是选择最好的路径进行扩展,不如考虑到有时扩展保留在相同内存块中的路径可能更有效。

不确定这是否仍然是一个开放的问题,刚刚看到这个问题。

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

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

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

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

最新更新