首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Nio2读取大文件

如何使用Nio2读取大文件
EN

Stack Overflow用户
提问于 2013-05-20 20:12:26
回答 2查看 1.6K关注 0票数 0

我正在尝试读取一个文本文件,到目前为止大约有3lakh行。

我读得怎么样?

我正在使用java.io.BufferedReader阅读

下面是一小段代码,它代表了我的方法。

代码语言:javascript
复制
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

代码语言:javascript
复制
br = Files.newBufferedReader(Paths.get(inputFileName), StandardCharsets.UTF_16);

它导致了下面的异常

代码语言:javascript
复制
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);

但是没有像我的逻辑中那样逐行阅读或迭代吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-20 20:41:06

任何将整个文件读入内存的方法都注定要失败。文件迟早会超出可用内存,程序将停止运行,必须完全重新设计。这不是一个好的失败模式,因为在此期间用户无能为力。你现在就在这一点上。您甚至雄心勃勃地想要用一个有数十万行的文件来尝试它。重新思考并一次处理一行。或者使用数据库。

别自欺欺人了。您正在使用java.io读取文件。这里的NIO2组件是最小的。并不是说你根本不需要它。

票数 2
EN

Stack Overflow用户

发布于 2013-05-20 21:03:31

内存不足异常

内存不足,因为您试图将过多的文件读取到内存中。这可能有两种我能想到的方式。

你是故意这样做的

如果你试图保存你读入的每一行,你将会耗尽或记忆。

代码语言:javascript
复制
while ((curentLine = br.readLine()) != null) {
    stringBuilder.append(currentLine);
}

如果您只想一次保存1000行代码,那么可以使用-Xmx增加Java的堆大小,这样就没问题了。这完全取决于1000行代码占用了多少内存。

你是不小心这么做的,

如果您正在读取的文件没有任何换行,那么br.readLine()将尝试读取整个文件,并认为它是一个巨大的长行。

不逐行阅读

如果你想象一个任意的文本文件,它只是一个很长的字符串。其中一些字符(EOL)对人类和许多程序都有特殊的意义,但它们仍然只是字符。这意味着您不能只说“给我第10行文本”,而不阅读前面的每个字符(因为您永远不知道哪个字符可能是您需要计算的EOL )。

您可以使用固定长度的记录格式:假设每行都是$n$字符长度(比如80个字符)。现在,如果您想跳到第10行,可以跳到第800个字符。但是如果你实际使用的是UTF-16,那么字符就不是char,这并不能真正起作用。

这没问题,因为此时您可能应该使用数据库。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16649263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档