在Java中对2个大型文本文件进行排序的最佳方法是什么?

时间:2013-04-26 08:25:50

标签: java sorting large-files

我正在构建一个简单的java应用程序,它涉及从csv文件中读取信息。 csv文件中的信息以这种形式出现:

"ID","Description"
"AB","Some sort of information for AB"
"AC","Some sort of information for AC"

我需要让用户在按ID排序的控制台中打印出描述,id或两者。最简单的解决方案是使用CSV库(如opencsv)解析文件,并将这些字符串放在TreeMap中,然后打印TreeMap的内容。 TreeMap中的键是ID,值是描述。

然而,CSV文件可能很庞大。它可能是5 GB,并且将5GB的字符串加载到TreeMap中会导致内存不足错误。为了处理大文件,我可以使用外部合并排序对文件进行排序。有一次,我得到了排序文件,我可以通过阅读文件将文件内容打印到控制台。

外部合并排序肯定比将文件内容加载到TreeMap要慢得多。我正在考虑检测文件大小。如果文件大小超过可用内存,那么我将使用外部合并排序。否则,我将把文件的内容加载到TreeMap中。

但是,这意味着将有两个单独的代码块执行2个不同的排序。因此增加了需要维护的代码量。如果您要编写此应用程序,您是否会考虑编写2个单独的代码代码来处理小型csv文件和单独的大型csv文件。或者您是否只使用外部合并排序对文件进行排序,而不管文件大小?

或者这种方法有替代方法吗?

谢谢。

2 个答案:

答案 0 :(得分:3)

自己解析csv文件,只向TreeMap添加ID列,因为值记录了该行的字节长度。然后打印使用RandomAccessFile来读取相应的行。如果这种方法仍然溢出你的记忆,请看看MapDB。它提供了无缝溢出到磁盘并具有出色性能的TreeMap实现。

答案 1 :(得分:1)

这取决于您的老板/客户为此分配多少资源。如果这不是问题,那么当然需要有一个带有2部分代码的优化版本:对于较小文件的快速内存排序和对于大文件的外部排序。

当客户想要一个快速的解决方案时,你可以问他:你想要一个缓慢的解决方案,它可以使用无限的文件大小,或者你想要一个具有内存限制的更快运行的解决方案? - 你会得到他想要的回复,而且他会很好:) - 如果客户满意的话也是如此。

也许他想要一个实现:如果软件没有完全支付,那么它只允许最大1GB的文件,等等。