2

我正在研究一个项目,该项目处理读取和处理包含某些个人的各种数据的巨大 .txt 文件。

多个文件将按单个 ID(存在于所有文件中)读取和排序,然后合并,即从分配给同一 ID 的所有文件中检索所有条目。换句话说,每个人在每个文件中都可以有多个条目(即行)。我需要检索我找到的关于一个 ID 的所有信息,将其存储起来,然后传递给下一个。

到目前为止,我已经尝试过FileChannel,FileInputStreamMappedFileBuffer,但显然最适合我的情况是FileInputStream使用 aBufferedReader和比较它们,我看到了Collection.sort()推荐的方法。一个重要的问题是我不知道要使用该应用程序的 PC 的性能,并且文件可能大于 2GB。任何帮助,将不胜感激。

4

2 回答 2

0

如果文件足够大,您将不得不使用外部排序,在这种情况下,数据库真正开始成为最实用的选择。JDK 中没有外部排序方法。

于 2012-09-11T09:53:12.470 回答
0

如果您希望处理的数据多于目标环境可以装入内存的数据,那么您将不得不使用某种形式的磁盘流式传输或多次重新解析文件。

选择哪个选项的决定取决于数据的分布。

如果每个 id 的行数相对较少(即很多不同的 id),那么假设您需要所有 id 的整理结果,重新解析将是最慢的。

如果 id 相对较少(即很多行),那么重新解析可能会变得更有效。

我的猜测是,在一般情况下,为每个 id 重新解析效率会很低(但如果你知道可能有 <10 个不同的 id,那么我会考虑一个基于重新解析的解决方案)

然后的想法是,您只需将结果放入一种列表映射中即可解析文件......

Map<Id,List<Record>>

你面临的问题是你没有足够的内存来保存这样的地图......

因此,您需要在磁盘存储上创建一个中间临时来保存每个 id 的列表。

磁盘存储有两种选择:

  1. 自己滚

  2. 使用数据库(例如 derby 或 hsqldb 或 ...)

选项 1 的工作量更大,但您可以针对您的用例进行优化(即仅通过追加写入,然后最后将所有记录读回并对其进行排序)

选项 2 将更容易和更快地实施,但有性能风险,因为数据库将在 id 上维护一个索引,以防您想在解析时随机读取数据(在此用例中您不会这样做)...

如果我必须选择,我会从选项 2 开始,并且只会给自己引入维护头痛,如果性能次优,选项 1 将是。(避免过早优化)

您将需要使用缓冲读取器(具有非常大(64k)的缓冲区,以避免通过竞争性读/写操作破坏磁盘(磁盘会降低性能)

于 2012-09-11T10:10:23.833 回答