我有许多输入文件,我正在并行读取并在我读取的每一行上执行计算。但是,对于每一行(在每个文件中),我需要访问大约一百个文件中的一个,遍历整个文件并将每个组合写入输出文件。
所以,基本上,我有类似的东西(注意,我只添加了代码的关键部分):
int numberOfFiles = (int) new File("path/").listFiles().length;
IntStream.range(0, numberOfFiles).parallel().forEach(k -> {
BufferedWriter bw = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(new File("priorityQueuePreTerminal"+k+".txt")));
bw = new BufferedWriter(new FileWriter(new File("priorityQueuePostTerminal"+k+".txt"), true));
...
try {
while( (line = br.readLine()) != null ){
...
BufferedReader br2 = new BufferedReader(new FileReader(new File("shared/"+i+".txt")));
while( (line2 = br2.readLine()) != null ){
bw.write(...);
}
}
} catch (Exception e) { } finally { br2.close(); }
} catch (Exception e) { } finally { br.close(); bw.close(); }
});
实质上发生的是,两个输入文件可以同时从这100个共享文件中的同一个读取。 最终的结果是,其中一个输出文件总是完全完成,就像它应该的那样,而所有其他输出文件都有起始的几行,然后它们过早地结束。
我甚至能够通过多个流从同一个共享文件中读取(我的印象是,通过多个资源从同一个文件读取很好,但写入可能有问题)?在Java 8流中是否有等效于synchronized
,以确保一个流当前只能从一个文件中读取?
答案 0 :(得分:2)
你好并行阅读文件是一个非常糟糕的主意。因为您的硬件硬盘驱动器受到某些数量的限制。可以说每秒700 MB。在某一点上,无论你在paralel中阅读多少,最终你都不会看到任何性能提升。尝试并行优化数据处理,而不是IO访问磁盘。
虽然不是真正的答案。我的建议是将所有文件读入内存或尽可能多地读入内存。然后在赋值的处理部分中进行多线程处理而不是文件读取。