Java:对巨大磁盘文件进行随机读取的最快方法

coc*_*two 6 java nio

我有一个中等大小的数据集,大约800 MB左右,这基本上是一个很大的预计算表,我需要将一些计算加速几个数量级(创建该文件需要几个mutlicores计算机天来使用优化生成和多线程算法......我真的需要那个文件).

现在已经计算了一次,那么800MB的数据是只读的.

我无法忍受它在记忆中.

截至目前,它是一个巨大的800MB文件,但如果可以提供帮助,拆分成较小的文件不是问题.

我需要在该文件中读取大约32位数据的大量时间.我不知道在哪里我需要读取这些数据:读取是均匀分布的.

在这样的文件或文件中随机读取Java的最快方法是什么?理想情况下,我应该从几个不相关的线程进行这些读取(但如果需要,我可以在单个线程中对读取进行排队).

Java NIO是可行的吗?

我不熟悉'内存映射文件':我想我不想在内存中映射800 MB.

我想要的只是访问这些800MB基于磁盘的数据的最快随机读取.

顺便说一下,如果人们想知道这与我不久前提出的问题完全不同:

Java:基于磁盘的快速哈希集

Stu*_*son 6

加载和存储在内存中的800MB并不多.如果你有能力让多核机器在数据集上连续几天被剥夺,那么你可以支付额外的GB或两个RAM,不是吗?

也就是说,阅读Java的java.nio.MappedByteBuffer.从您的评论中可以清楚地看出"我认为我不想在内存中映射800 MB"这个概念并不清楚.

在一个坚果shell中,映射的字节缓冲区允许以编程方式访问内存中的数据,尽管它可能在磁盘上或内存中 -这是由操作系统决定的,因为Java的MBB基于操作系统的虚拟内存子系统.它也很好而且快速.您还可以安全地从多个线程访问单个MBB.

以下是我建议您采取的步骤:

  1. 实例化将数据文件映射到MBB的MappedByteBuffer.创作有点贵,所以请保持它.
  2. 在你的查找方法......
    1. 实例化一个byte[4]数组
    2. 呼叫 .get(byte[] dst, int offset, int length)
    3. 字节数组现在将拥有您的数据,您可以将其转换为值

并且presto!你有你的数据!

我是MBB的忠实粉丝,并且过去曾成功地将它们用于此类任务.


Kon*_*rus 2

RandomAccessFile(阻止)可能有帮助:http://java.sun.com/javase/6/docs/api/java/io/RandomAccessFile.html

您还可以使用FileChannel.map()将文件区域映射到内存,然后读取MappedByteBuffer.

另请参阅:http ://java.sun.com/docs/books/tutorial/essential/io/rafs.html