在Haskell中处理大文件

10

我有一个大文件(4GB以上)的内容,可以把它理解为4字节浮点数。我想把它当作列表来处理,也就是说我想使用map、filter、foldl等方法对其进行操作。但是,与其生成一个新的列表输出,我希望能够将输出写回到文件中,这样只需要在内存中加载小部分文件。你可以说我需要一种名为MutableFileList的类型。

有人遇到过这种情况吗?我想知道是否有一种Hackish的方法来处理这个问题,而不是重新发明轮子?

3个回答

13

您不应该将其视为内存中的[Double][Float]。您可以使用列表式打包数组类型之一,例如uvector/vector/…与mmapFile或readFile一起使用,在处理它们时每次拉取文件的块。或者使用一种延迟打包数组类型,相当于延迟字节串。


1
你在 Haskell 社区的知名度已经和 Jon Skeet 一样高了。你只要发帖就能得到点赞。 :p - Rayne

9

这个链接 对你很有帮助。你可以使用 readFilewriteFile 完成你需要做的事情,而且它们都是惰性的。它只在仍在使用时保留内存中的内容,所以你可以读取、处理和写出文件,而不会让电脑崩溃。


哦,我没意识到这些值会被从内存中清除。好的,我会试一下。 - Jonathan Fischoff

1

你可以使用 mmap 将文件映射到内存中,然后进行处理。有一个mmap 模块承诺可以读写 mmaped 文件,甚至可以使用惰性映射的文件块,但我没有尝试过。

写入映射文件的接口似乎相当低级,因此您需要构建自己的抽象或使用Foreign.Ptr等工具。


@Jonathan:你确定它不起作用吗?文档说该模块使用 CreateFileMappingMapViewOfFile,两者都支持64位文件大小/偏移参数,因此这些API调用应该适用于任何大小的文件(例如 http://msdn.microsoft.com/en-us/library/aa366761%28VS.85,lightweight%29.aspx )。那么该模块是否以某种方式破坏了这个功能呢? - sth
@sth 老实说,我不确定。我是根据网上的阅读来判断的。我在这个网站上看到了有关内存映射文件限制的线程。我没有在MSDN上看到任何指定大小要求的内容,但是无论如何,我认为程序无论如何都不能获得超过2GB的内存。我有点想要反向的文件映射内存 :) - Jonathan Fischoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接