我正在尝试读取一个文本文件,到目前为止大约有3lakh行。
我读得怎么样?
我正在使用java.io.BufferedReader阅读
下面是一小段代码,它代表了我的方法。
int lineNumber = 1;
BufferedReader br = null;
String currentLine = null;
br = new BufferedReader(new FileReader(f));//here f will be the file name to be read, I have passed
while ((cuurentLine = br.readLine()) != null) {
//here I have written logic to do processing after reading 1000 lines
//line number = 1001 start processing, similarly it reads next 1000 lines, each line is put in a List collection
//after reaching 1001 line clearing list and continuing the loop
}我在下面的案例中尝试过使用NIO2
br = Files.newBufferedReader(Paths.get(inputFileName), StandardCharsets.UTF_16);它导致了下面的异常
exception :Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuffer.append(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at TexttoExcelMerger.readFileLineByLine(TexttoExcelMerger.java:66)
at TexttoExcelMerger.main(TexttoExcelMerger.java:255)首先,我的方法正确吗?
在NIO2,apache FileUtils或任何其他API中,有没有什么高效快速的方法来更快地读取文件,从而更快地改进我的文件读取过程。我可以读一组像first 1000这样的行吗
br.readFirst(1000);,
但是没有像我的逻辑中那样逐行阅读或迭代吗?
发布于 2013-05-20 20:41:06
任何将整个文件读入内存的方法都注定要失败。文件迟早会超出可用内存,程序将停止运行,必须完全重新设计。这不是一个好的失败模式,因为在此期间用户无能为力。你现在就在这一点上。您甚至雄心勃勃地想要用一个有数十万行的文件来尝试它。重新思考并一次处理一行。或者使用数据库。
别自欺欺人了。您正在使用java.io读取文件。这里的NIO2组件是最小的。并不是说你根本不需要它。
发布于 2013-05-20 21:03:31
内存不足异常
内存不足,因为您试图将过多的文件读取到内存中。这可能有两种我能想到的方式。
你是故意这样做的
如果你试图保存你读入的每一行,你将会耗尽或记忆。
while ((curentLine = br.readLine()) != null) {
stringBuilder.append(currentLine);
}如果您只想一次保存1000行代码,那么可以使用-Xmx增加Java的堆大小,这样就没问题了。这完全取决于1000行代码占用了多少内存。
你是不小心这么做的,
如果您正在读取的文件没有任何换行,那么br.readLine()将尝试读取整个文件,并认为它是一个巨大的长行。
不逐行阅读
如果你想象一个任意的文本文件,它只是一个很长的字符串。其中一些字符(EOL)对人类和许多程序都有特殊的意义,但它们仍然只是字符。这意味着您不能只说“给我第10行文本”,而不阅读前面的每个字符(因为您永远不知道哪个字符可能是您需要计算的EOL )。
您可以使用固定长度的记录格式:假设每行都是$n$字符长度(比如80个字符)。现在,如果您想跳到第10行,可以跳到第800个字符。但是如果你实际使用的是UTF-16,那么字符就不是char,这并不能真正起作用。
这没问题,因为此时您可能应该使用数据库。
https://stackoverflow.com/questions/16649263
复制相似问题