我遇到了一个有点奇怪的情况。
我正在将大小约为500MB的文件从FileInputStream复制到FileOutputStream。 这个过程非常顺利(大约需要500毫秒)。 当我第一次关闭这个FileOutputStream时,它只需要大约1毫秒。
但是问题来了,当我再次运行此操作时,每次连续的关闭都需要大约1500-2000毫秒! 删除此文件后,持续时间会回归到1毫秒。
我是否缺少了一些重要的java.io知识?
这似乎与操作系统有关。 我在ArchLinux上运行(相同的代码在Windows 7上每次都不到20毫秒)。 请注意,无论它在OpenJDK还是Oracle的JDK中运行,结果都一样。 硬盘是具有ext4文件系统的固态驱动器。
下面是我的测试代码:
public void copyMultipleTimes() throws IOException {
copy();
copy();
copy();
new File("/home/d1x/temp/500mb.out").delete();
copy();
copy();
// Runtime.getRuntime().exec("sync") => same results
// Thread.sleep(30000) => same results
// combination of sync & sleep => same results
copy();
}
private void copy() throws IOException {
FileInputStream fis = new FileInputStream("/home/d1x/temp/500mb.in");
FileOutputStream fos = new FileOutputStream("/home/d1x/temp/500mb.out");
IOUtils.copy(fis, fos); // copyLarge => same results
// copying takes always the same amount of time, only close "enlarges"
fis.close(); // input stream close this is always fast
// fos.flush(); // has no effect
// fos.getFD().sync(); // Solves the problem but takes ~2.5s
long start = System.currentTimeMillis();
fos.close();
System.out.println("OutputStream close took " + (System.currentTimeMillis() - start) + "ms");
}
输出结果如下:
OutputStream close took 0ms
OutputStream close took 1951ms
OutputStream close took 1934ms
OutputStream close took 1ms
OutputStream close took 1592ms
OutputStream close took 1727ms
close
(当然是在long start = System.currentTimeMillis();
之前)之前明确地flush
fos
吗? - A4L