乍一看这段代码似乎完全没问题
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("1.txt"));
byte[] bytes = new byte[4096];
bout.write(bytes);
bout.close();
但如果我们仔细研究一下,我们会看到close()
实现如下
public void close() throws IOException {
try {
flush();
} catch (IOException ignored) {
}
out.close();
}
是否可能由于flush()
错误而被忽略,数据可能会丢失并且程序不会注意到它?在FilterOutputStream.close
(BufferedOutputStream
继承close()
)API中没有提到任何危险。
UPDATE:为了在close()期间模拟IO错误,我改变了测试以写入闪存,在bout.close()之前添加了5秒的睡眠,并且在测试休眠时我删除了来自USB的Flash。测试完成没有例外,但是当我插入Flash并检查它时 - 1.txt不存在。
然后我覆盖了close()
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("g:/1.txt")) {
@Override
public void close() throws IOException {
flush();
super.close();
}
};
再次运行测试并获得
Exception in thread "main" java.io.FileNotFoundException: g:\1.txt (The system cannot the specified path)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:104)
at test.Test1.main(Test1.java:10)
答案 0 :(得分:6)
实际上,我认为调用close
确实会让你丢失数据,因为这个潜在的IOException
被忽略了(谁知道开发人员想要通过什么来做到这一点) ...)。
一个不错的选择,虽然它确实将努力放在程序员的一边,但是在flush
之前明确地调用close
(正确处理潜在的IOException
),就像在@Tom的评论,特别是在try/finally
块中。
由于AutoCloseable
对象,Java7中的这个问题可能会进一步加剧,因为你不会明确地调用close()
方法,这种解决方法更容易被忽略。 / p>