java.io.BufferedOutputStream可以安全使用吗?

时间:2013-01-23 10:46:29

标签: java

乍一看这段代码似乎完全没问题

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.closeBufferedOutputStream继承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)

1 个答案:

答案 0 :(得分:6)

实际上,我认为调用close确实会让你丢失数据,因为这个潜在的IOException被忽略了(谁知道开发人员想要通过什么来做到这一点) ...)。

一个不错的选择,虽然它确实将努力放在程序员的一边,但是在flush之前明确地调用close(正确处理潜在的IOException),就像在@Tom的评论,特别是在try/finally块中。

由于AutoCloseable对象,Java7中的这个问题可能会进一步加剧,因为你不会明确地调用close()方法,这种解决方法更容易被忽略。 / p>