打印行,Java堆空间

6

我想打印一份巨大文本文件的每一行(超过 600,000 MB)。

但是,当我尝试下面的代码时,在达到第1,000,000行之前就会出现“...OutOfMemoryError:Java堆空间”。

有没有更好的方法来处理输入,而不是使用 FileReader 和 LineNumberReader?

FileReader fReader = new FileReader(new File("C:/huge_file.txt"));
LineNumberReader lnReader = new LineNumberReader(fReader);
String line = "";
while ((line = lnReader.readLine()) != null) {
    System.out.println(lnReader.getLineNumber() + ": " + line);
}
fReader.close();
lnReader.close();

提前感谢您!


感谢大家的回答!

我最终找到了内存泄漏的原因,是一个未使用的Java类实例,它在每个行迭代中复制自己。换句话说,它与文件加载部分无关。


5
你所拥有的代码不会产生OutOfMemoryError,导致问题的原因更可能是你对数据的处理方式。 - Peter Lawrey
5
有这么大的文本文件,你觉得里面可能有一行非常长的内容吗? - Björn Pollex
2
同时管理一个600GB的文本文件会变得缓慢而繁琐。您应该考虑使用较小的文本文件。 - Peter Lawrey
4
正如SpaceCowboy所建议的那样,你需要大约5倍于内存中最长行的空间。尝试使用System.out.print(lnReader.getLineNumber() + ": "); System.out.println(line);,它避免了创建第二个包含整个行和更多内容的StringBuilder/String。 - Peter Lawrey
1
我在以前的项目中不得不处理大量文本文件的批量导入。最终,我将此部分分离为Perl脚本 - 它不仅使用更少的内存,而且运行速度快了约60倍(4小时缩短至4分钟)。如果性能成为问题,您可能需要考虑这一点。 - Alan Escreet
显示剩余6条评论
3个回答

1

LineNumberReader 扩展了 BufferedReader。可能是缓冲读取器缓冲太多了。通过分析器运行程序应该能够毫无疑问地证明这一点。

BufferedReader 的构造函数之一需要一个缓冲区大小,这个构造函数也在行号读取器中可用。

替换为:

LineNumberReader lnReader = new LineNumberReader(fReader);

使用:

LineNumberReader lnReader = new LineNumberReader(fReader, 4096);

0

0

使用这个类来读取文件:RandomAccessFile,那么您就不会再遇到内存不足的问题了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接