在Java中逐行读取文本文件的最快方法

对于日志处理,我的应用程序需要逐行读取文本文件。 首先我使用了BufferedReader的readLine()函数,但我在网上读到BufferedReader在读取文件时速度很慢。
之后我尝试将FileInputStream与FileChannel和MappedByteBuffer一起使用,但在这种情况下,没有类似于readLine()的函数,所以我在文本中搜索换行符并处理它:

try { FileInputStream f = new FileInputStream(file); FileChannel ch = f.getChannel( ); MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0L, ch.size()); byte[] bytes = new byte[1024]; int i = 0; while (mb.hasRemaining()) { byte get = mb.get(); if(get == '\n') { if(ra.run(new String(bytes))) cnt++; for(int j = 0; j<=i; j++) bytes[j] = 0; i = 0; } else bytes[i++] = get; } } catch(Exception ex) { ex.printStackTrace(); } 

我知道这可能不是实现它的好方法,但是当我以字节为单位读取文本文件时,它比使用BufferedReader快3倍,但调用new String(bytes)会创建一个新的String并使程序更慢然后当使用BufferedReader。
所以我想问一下逐行读取文本文件的最快方法是什么? 有人说BufferedReader是解决这个问题的唯一方法。

PS: ra是来自dk.brics.Automaton库的RunAutomaton的一个实例。

我非常怀疑BufferedReader会导致很大的开销。 添加自己的代码可能至少效率低下,而且很可能也是错误的。

例如,在您给出的代码中,您正在调用new String(bytes) ,它总是要创建一个1024字节的字符串,使用平台默认编码…不是一个好主意。 当然,你之后清除了数组,但你的字符串仍然包含一堆’\ 0’字符 – 这意味着除了其他任何东西之外还有很多浪费的空间。 您至少应该限制​​创建字符串的字节数组的部分(这也意味着您之后不需要清除该数组)。

您是否真的尝试过使用BufferedReader并发现它太慢了? 您通常应该编写最符合您目标的最简单的代码,然后检查它是否足够快……特别是如果您不这样做的唯一原因是您“在互联网上阅读”的未指定资源。 您是否希望我找到数百个人们喷出不正确的性能建议的例子? 🙂

作为替代方案,您可能希望查看Guava对Files.readLines()的重载,它接受一个LineProcessor

使用普通的BufferedReader我得到100+ MB / s 。 您可以从磁盘读取数据的速度很可能是您的瓶颈,因此您的阅读方式不会产生太大影响。

BufferedReader不是唯一的解决方案,但它对99%的用例来说足够快,那么为什么要让事情变得比他们需要的更复杂呢?

框架是一种替代方案吗?

我不知道性能,但是

http://commons.apache.org/io/

http://commons.apache.org/io/api-release/index.html请参阅IOUtils类

为这种情况定义了非常容易使用的帮助程序类。

根据这篇 SOpost,您可能还想给Scanner类一个镜头。

我有一个非常简单的循环,它使用BufferedReader从sdcard上的文件中读取大约2000行(50k字节),并且在galaxy选项卡2上以调试模式在大约100mS内读取所有这些行。不是太糟糕。 然后我把一个扫描仪放在循环中,时间经过了屋顶(几十秒),还有很多GC_CONCURANT消息

 Scanner scanner = new Scanner(line); int eventType = scanner.nextInt(16); 

所以至少在我的情况下它的扫描仪就是问题,我想我需要另外扫描一下,但我不知道它为什么会这么慢