我有一个要求,我需要逐行编写文本文件。 行数可达80K。我打开文件输出流并在for循环中,迭代列表并形成一行并将该行写入文件。
这意味着对文件进行了80K写操作。
频繁打开和写入文件会影响性能。 任何人都可以建议在Java IO中满足此要求的最佳方式吗?
感谢。
答案 0 :(得分:3)
您尚未发布任何代码,但只要您的写入被缓冲,您几乎不会注意到性能。使用BufferedWriter.write()
后跟BufferedWriter.newLine(),
,尽可能避免冲洗。不要'形成一条线',只要你有它就写下你必须写的东西。如果不是你所观察到的所有开销实际上可能是字符串连接而不是I / O.
其他答案中提到的替代方案或者相当于以更多巴洛克方式实施,或者涉及NIO,这不会更快。
答案 1 :(得分:2)
使用BufferedOutputStream
。有了它,所有写入首先写入缓冲区而不是直接写入磁盘。仅当缓冲区已满并且关闭或刷新流时,才会写入磁盘。默认缓冲区大小为8192字节,但您可以指定自己的缓冲区大小。
以下是使用默认缓冲区大小的示例:
PrintWriter out = null;
try {
out = new PrintWriter(new OutputStreamWriter(
new BufferedOutputStream(new FileOutputStream("out.txt")), "UTF-8"));
for(int i = 0; i < 80000; i++) {
out.println(String.format("Line %d", i));
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if(out != null) {
out.flush();
out.close();
}
}
答案 2 :(得分:0)
以下是我在设计快速文件IO时使用的启发式方法,以及一组用于测试不同备选方案的基准测试。
启发式:
我前一段时间写过以下文件基准测试。给他们一个跑步:https://gist.github.com/kirkch/3402882
当我运行benchmarks时,对着标准的旋转磁盘,我得到了这些结果:
Stream Write: 438
Mapped Write: 28
Stream Read: 421
Mapped Read: 12
Stream Read/Write: 1866
Mapped Read/Write: 19
所有数字均以毫秒为单位,因此越小越好。请注意,内存映射文件始终执行其他所有方法。
在编写这些类型的系统时,我发现的另一个惊喜是,在Java的更高版本中,使用BufferedWriter可能比直接使用FileWriter或RandomAccessFile慢。事实证明,缓冲现在已经降低了,我认为它发生在Sun重写java.io以使用通道和字节缓冲区时。然而,添加自己的缓冲的建议仍然是常见的做法。当您首先测量目标环境时,请随意调整上面的基准代码以进行进一步的实验。
在寻找支持上述一些事实的链接时,我遇到了Martin Thompson's post on this topic。非常值得一读。