在java中对巨大的file.txt进行排序

我正在处理一个非常大的文本文件(755Mb)。 我需要对行(约1890000)进行排序,然后将它们写回另一个文件中。

我已经注意到有一个起始文件的讨论与我的相似: 排序行根据其中的单词作为键

问题是我无法将行存储在内存中的集合中,因为我得到了Java堆空间exception(即使我最大限度地扩展它)..(已经尝试过!)

我不能用excel打开它并使用排序function,因为文件太大而且无法完全加载..

我想过使用DB ..但我认为编写所有行然后使用SELECT查询它在执行时间方面太长了……我错了吗?

任何提示赞赏提前谢谢

我认为这里的解决方案是使用临时文件进行合并排序:

  1. 读取第一个文件的前n行( n是你能够在内存中存储和排序的行数),对它们进行排序,然后将它们写入文件1.tmp (或者你可以调用它)。 对接下来的n行执行相同操作并将其存储在2.tmp 。 重复,直到处理完原始文件的所有行。

  2. 阅读每个临时文件的第一行。 确定最小的一个(根据您的排序顺序),将其写入目标文件,并从相应的临时文件中读取下一行。 重复,直到处理完所有行。

  3. 删除所有临时文件。

只要您有足够的磁盘空间,这适用于任意大文件。

您可以运行以下命令

 -mx1g -XX:+UseCompressedStrings # on Java 6 update 29 -mx1800m -XX:-UseCompressedStrings # on Java 6 update 29 -mx2g # on Java 7 update 2. 

 import java.io.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Main { public static void main(String... args) throws IOException { long start = System.nanoTime(); generateFile("lines.txt", 755 * 1024 * 1024, 189000); List lines = loadLines("lines.txt"); System.out.println("Sorting file"); Collections.sort(lines); System.out.println("... Sorted file"); // save lines. long time = System.nanoTime() - start; System.out.printf("Took %.3f second to read, sort and write to a file%n", time / 1e9); } private static void generateFile(String fileName, int size, int lines) throws FileNotFoundException { System.out.println("Creating file to load"); int lineSize = size / lines; StringBuilder sb = new StringBuilder(); while (sb.length() < lineSize) sb.append('-'); String padding = sb.toString(); PrintWriter pw = new PrintWriter(fileName); for (int i = 0; i < lines; i++) { String text = (i + padding).substring(0, lineSize); pw.println(text); } pw.close(); System.out.println("... Created file to load"); } private static List loadLines(String fileName) throws IOException { System.out.println("Reading file"); BufferedReader br = new BufferedReader(new FileReader(fileName)); List ret = new ArrayList(); String line; while ((line = br.readLine()) != null) ret.add(line); System.out.println("... Read file."); return ret; } } 

版画

 Creating file to load ... Created file to load Reading file ... Read file. Sorting file ... Sorted file Took 4.886 second to read, sort and write to a file 

算法:

我们有多少内存可用? 假设我们有可用的X MB内存。

  1. 将文件分为K块,其中X * K = 2 GB 。 将每个块放入内存并使用任何O(n log n)算法照常排序。 将行保存回文件。

  2. 现在将下一个块带入内存并进行排序。

  3. 完成后,将它们逐个合并。

上述算法也称为外部排序。 步骤3称为N路合并

分而治之是最好的解决方案:)

将文件分成较小的文件,单独对每个文件进行排序然后重新组合。

链接:

给定内存约束时,对具有大量数据的文件进行排序

http://hackerne.ws/item?id=1603381

为什么不尝试multithreading并增加正在运行的程序的堆大小? (这也要求你使用合并排序类的东西,只要你的系统中有超过755mb的内存。)

也许你可以使用perl来格式化文件。并像mysql一样加载到数据库中。 它太快了。 并使用索引来查询数据。 并写入另一个文件。

你可以设置jvm堆大小,如’-Xms256m -Xmx1024m’。我希望能帮助你。谢谢你