4

我刚刚读取了一个大小为167MB,行号为1884000的文件。我使用的方法是BufferedReader得到一行读取的效果。

我注意到的是,随着当前行号的增加,读取文件的过程变得越来越慢(在这种情况下,我了 3 小时 30 分钟完成它)。

我知道使用nio可能会加快此过程,但我想在线读取文件。

我的代码如下;谁能给我一些建议?非常感谢!

String htmlContentPath = html.getAbsolutePath();
BufferedReader reader = new  BufferedReader(new InputStreamReader(new FileInputStream(htmlContentPath)));
String line = null;
int cnt = 0;
while((line = reader.readLine()) != null)       {
    this.proc(line);
    if((cnt++ % 2000) == 0) {
        logger.info("current line number:\t"+cnt);
    }
}
4

4 回答 4

2

你应该可以在这里找到答案:

http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly

为了获得最佳的 Java 读取性能,需要记住四件事:

  • 通过一次读取一个数组而不是一次读取一个字节来最小化 I/O 操作。一个 8Kbyte 的数组是一个很好的大小。

  • 通过一次获取一个数组而不是一次获取一个字节来最小化方法调用。使用数组索引来获取数组中的字节。

  • 如果您不需要线程安全,请尽量减少线程同步锁。要么减少对线程安全类的方法调用,要么使用非线程安全类,如 FileChannel 和 MappedByteBuffer。

  • 最大限度地减少 JVM/OS、内部缓冲区和应用程序阵列之间的数据复制。将 FileChannel 与内存映射或直接或包装数组 ByteBuffer 一起使用。

于 2013-08-08T15:46:24.623 回答
0

这可能是由交换引起的,具体取决于 proc 方法中文件的内存占用,您可以在进程上执行 visualVM 以查看堆状态,然后调整(xms,xmx)/减少您的内存消耗方法。

干杯。

于 2013-08-08T15:44:52.153 回答
0

当我第一次阅读您的问题时,我将建议您注释掉对 proc() 的调用,然后使用其他一些答案来加快文件的读取速度(这应该是整个执行时间,因为您注释掉了处理称呼)。

进一步考虑,我建议您使用分析器(没有注释掉任何行) 如果您使用的是 Eclipse,那么 Eclipse Marketplace 上有几个 JVM 分析器,我确信也有集成到其他 IDE 中的配置文件。分析器可以向您显示代码中的热点——您似乎大部分时间都在的地方。这些信息,加上您对程序逻辑的了解,将产生加速最严重瓶颈的方法。

这是一个迭代过程,结果越来越好。

我还建议您首先使用小得多的示例文件进行测试。

于 2013-08-08T16:01:50.503 回答
0

这对我来说听起来像是一个内存问题(由于内存不足,垃圾收集的需求增加,通常会出现减速)。

您发布的代码看起来不应该随着行号的增加而变慢(假设 proc() 调用是“干净的”)。

我第二个 Chris G 建议删除 proc() 调用,以查看当您只是阅读罚款而不处理其任何行时是否仍然会出现减速。

我还要补充一点,您可以尝试使用 -Xmx 和 -Xms 标志让 JVM 一开始就可以访问更多内存。

这是一个可能相关的问题: Java线程在处理结束时变慢

于 2013-08-08T16:17:01.227 回答