Java 处理数十亿字节

Posted

技术标签:

【中文标题】Java 处理数十亿字节【英文标题】:Java handling billions bytes 【发布时间】:2011-11-02 17:32:00 【问题描述】:

我正在Java中创建一个压缩算法; 要使用我的算法,我需要大量有关目标文件结构的信息

收集数据后,我需要重新读取文件。

在重新读取文件时,我通过将文件数据'转换' 使其成为一个很好的压缩目标,使其成为一种相当特殊的格式。然后我压缩它。

问题现在是:

    我不想打开新的 FileInputStream 来重新读取文件。 我不想将转换后的文件(通常是目标文件大小的 150%)保存到磁盘。

有什么方法可以'重置' FileInputStream 以移动到文件的开头,以及如何存储大量'转换'数据高效而不写入磁盘?

【问题讨论】:

【参考方案1】:

您可以使用一个或多个 RandomAccessFiles。您可以将它们内存映射到不消耗堆(实际上它们使用大约 128 个字节)或直接内存但可以随机访问的 ByteBuffer()。

您的临时数据可以存储在直接 ByteBuffer(s) 或更多内存映射文件中。由于您可以随机访问原始数据,因此您可能不需要在内存中复制您想象的那么多数据。

这样,您只需几 KB 的堆就可以访问整个数据。

【讨论】:

【参考方案2】:

reset 方法,但您需要将FileInputStream 包装在BufferedInputStream 中。

【讨论】:

reset() 要求缓冲调用 mark() 和 reset() 之间的所有数据。 @PeterLawrey 是的,我意识到发布后会删除。 我认为这是一个很好的解决方案,只是在这里不太好用。【参考方案3】:

您可以使用 RandomAccessFile,或者 java.nio ByteBuffer 是您正在寻找的。 (我不知道。)

资源可能被管道/流保存:立即写入压缩流。

回答您关于重置的问题:不可能;基类 InputStream 提供了标记和重置标记,但 FileInputStream 已针对多个操作系统进行了优化,并且只进行顺序输入。关闭和打开是最好的。

【讨论】:

用缓冲输入包装文件输入是解决这个问题的方法。但是,在这种情况下不合适。

以上是关于Java 处理数十亿字节的主要内容,如果未能解决你的问题,请参考以下文章

处理数十亿条记录的推荐数据库类型

在 MongoDB 中快速搜索数十亿个小文档的策略

SeaweedFS —— 可存储数十亿文件的分布式文件系统

深入理解计算机系统(第二版)----之二:信息的表示和处理

如何存储数十亿 JSON 文件并进行查询

HiveQL:模式设计