【问题标题】:Is java.io.BufferedOutputStream safe to use?java.io.BufferedOutputStream 可以安全使用吗?
【发布时间】:2013-01-06 19:37:45
【问题描述】:

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

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 中没有提到任何危险。

更新:为了模拟 close() 期间的 IO 错误,我将测试更改为写入闪存,在 bout.close() 之前添加了 5 秒睡眠,而在测试睡眠时我删除了来自 USB 的闪存。测试无一例外地完成,但是当我插入 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)

【问题讨论】:

  • FilterOutputStream 错字?
  • 它显示为 openjdk close() 方法中的错误。 - 死店忽略...
  • @Nikolay 不,不是。 BufferedOuptutStream 从那里继承 close,忘了提
  • 有几个关于该问题的错误报告,例如bugs.sun.com/view_bug.do?bug_id=7015589。我个人认为这可能是您的应用程序的一个问题。我在使用BufferedOutputStream 时使用的解决方法是在close() 之前调用flush()。这类似于 JDK 实现,但在我的情况下,我会看到来自 flush() 的错误。
  • @pcalcao,没关系。请继续回答,因为它包含更多详细信息,例如AutoCloseable

标签: java


【解决方案1】:

事实上,我认为调用close 确实会让你丢失数据,因为潜在的IOException 被默默地忽略了(谁知道开发人员是怎么做的……) .

一个不错的选择,虽然它确实把精力放在了程序员的一边,是在close 之前显式调用flush(正确处理潜在的IOException),就像@Tom 在评论中提到的那样,特别是在try/finally 块中。

由于AutoCloseable 对象,这个问题在Java7 中可能会进一步恶化,因为您不会显式调用close() 方法,而且这种变通方法更容易被忽略。

【讨论】:

  • 可能是因为他们没有抑制异常,所以他们不知道如何处理来自flush()的异常。
  • 我认为抛出异常并让用户明确知道出了问题会更安全。
猜你喜欢
  • 2018-03-20
  • 2010-10-11
  • 2016-04-28
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多