Ami*_*ela 8 java file bufferedreader
我正在读取一个50G文件,其中包含由换行符分隔的数百万行.目前我使用以下语法来读取文件
String line = null;
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("FileName")));
while ((line = br.readLine()) != null)
{
// Processing each line here
// All processing is done in memory. No IO required here.
}
Run Code Online (Sandbox Code Playgroud)
由于文件太大,需要2小时才能处理整个文件.我可以改进从硬盘读取文件,以便IO(读取)操作花费最少的时间.我的代码限制是我必须处理每一行的顺序.
Joo*_*kka 10
它需要2小时来处理整个文件.
50 GB/2小时约等于7 MB/s.这根本不是一个糟糕的比率.一个好的(现代)硬盘应该能够持续保持更高的速率,所以也许你的瓶颈不是I/O?您已经在使用BufferedReader,就像名称所说的那样,缓冲(在内存中)读取的内容.您可以尝试使用比默认大小(8192字节)更大的缓冲区来创建阅读器,如下所示:
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("FileName")), 100000);
Run Code Online (Sandbox Code Playgroud)
请注意,使用默认的8192字节缓冲区和7 MB/s的吞吐量,BufferedReader将每秒重新填充其缓冲区大约1000次,因此降低该数量可能真的有助于减少一些开销.但是,如果您正在进行的处理(而不是I/O)是瓶颈,那么没有I/O技巧会对您有所帮助.您应该考虑将其设置为多线程,但它是否可行,以及如何,取决于此处的"处理"含义.
你唯一的希望是并行阅读和处理内部的内容.您的策略应该是永远不要求整个文件内容立即存在内存中.
首先分析您必须查看的代码,以查看花费的时间.重写占用时间最多的部分并重新配置以查看它是否有所改进.不断重复,直到获得可接受的结果.
我会考虑Hadoop和分布式解决方案.现在可以例行处理比您大的数据集.您可能需要在思考方面更有创意.
如果没有NIO,您将无法打破吞吐量障碍.例如,尝试使用new Scanner(File)而不是直接创建读者.最近我看了一下源代码,它使用了NIO的文件通道.
但我建议的第一件事是运行一个空循环BufferedReader,除了阅读之外什么都不做.注意吞吐量 - 并且还要关注CPU.如果循环落在CPU上,那么IO代码肯定存在问题.