在Haskell中对大文件进行随机访问

8
什么是在Haskell中读取大文件(约1 TB)的最佳方法? 基本上,该文件包含整数数据矩阵。 我可能需要(高效地)计算不同行或列之间的相关性。 我之前使用过pytables来完成这个任务,但是想尝试在Haskell中实现相同的操作。 我知道Haskell有一些hdf5绑定,但是否还有其他选项我不知道呢?

1
尝试使用Lazy ByteString,网址为http://lambda.haskell.org/platform/doc/current/ghc-doc/libraries/bytestring-0.10.0.2/index.html。 - viorior
1
@viorior,您能否详细说明一下如何使用惰性的bytestring进行随机访问?例如,如何从1TB文件中读取最后1KB,然后从中间读取1KB,再从开头读取1KB等等?据我所见,这样做会导致内存溢出错误。 - Yuras
@Yuras 和 Roman 建议的方式一样,或者使用更具体的库 - GHC.IO.HandleGHC.IO.Handle.FD - wit
我们可以安全地假设该平台为64位吗? - comonad
@comonad,是的,在这种情况下,我的机器是64位系统。简单介绍一下,它是一个Windows 64位系统。我正在使用Haskell平台。但由于这台机器没有连接到互联网,所以我最终不得不手动下载所有软件包及其依赖项,然后安装它们。 - Abhijit Ray
3个回答

13

就像其他语言一样:您使用 System.IO.hSeek 进行查找,然后使用二进制 I/O (Data.ByteString.hGet)。 然后解析结果(例如使用 attoparsec),并根据需要进行处理。


10

您也可以尝试使用mmap。例如,您可以将整个文件映射为ByteString:

import Data.ByteString as B
import System.IO.MMap

main = do
    bs <- mmapFileByteString "myLargeFile" Nothing
    let l = B.length bs
    print l
    -- print last 1024 bytes:
    let bs2 = B.drop (l - 1024) bs
    print (B.unpack bs2)

剪切一部分很快 - 不会复制任何数据。然后,您可以使用任何工具解析 ByteString


当 overcommit 被关闭时会失败。 - Boyd Stephen Smith Jr.

4
考虑使用迭代器包。它支持寻找attoparsec-iteratee包将其与attoparsec集成。
Roman建议的hSeek+hGet方法是低级别的方法。iteratee是一种更高级别的方法,但对初学者可能更难。

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