【问题标题】:Using flush() before close()在 close() 之前使用 flush()
【发布时间】:2012-04-09 03:38:52
【问题描述】:

根据 java 文档,在任何 java.io 流上调用 close() 都会自动调用 flush()。但是我在很多例子中看到,即使在生产代码中,开发人员在 close() 之前明确地使用了 flush()。在什么情况下我们需要在 close() 之前使用 flush()?

【问题讨论】:

  • 这个问题可能对你有点帮助[看这个][1] [1]:stackoverflow.com/questions/7300676/when-to-use-flush-in-java
  • @Siva:as per the Javadoc。引用和链接,或者它不存在。据我所知,一些 流实现将在关闭时刷新,而其他则不会。如果不是这种情况,请证明我错了,Javadoc 另有说明。
  • 与 haylem 相同的问题。我阅读了一些类的 Java API 文档,有人说flush()close() 中被调用,而其他人则没有做出任何这样的评论。有链接吗?

标签: java iostream


【解决方案1】:

开发者养成了在写完必须发送的东西后调用flush()的习惯。

恕我直言,在刚刚写入时使用 flush() 然后 close() 很常见,例如

// write a message
out.write(buffer, 0, size);
out.flush();

// finished
out.close();

如您所见,flush() 是多余的,但意味着您正在遵循一种模式。

【讨论】:

  • 冗余 + 模式 = 反模式?
  • 取决于实施类,这可能不是多余的。例如,如果 someinterface.getOutputStream() 返回一个 OutputStream,如果没有明确记录,您可能不知道 close 方法是否调用了 flush 或 flush 方法是否为空。例如。 URLConnection.getOutputStream(): docs.oracle.com/javase/8/docs/api/java/net/…
【解决方案2】:

我猜在很多情况下是因为他们不知道close() 也调用flush(),所以他们想要安全。

无论如何,使用缓冲流应该使手动刷新几乎是多余的。

【讨论】:

  • 赞成。实际上,任何人都不应该假设所有close() 也调用flush()
  • @JinKwon 他们完全有权对任何扩展 FilterOutputStream 的输出流执行此操作:请参阅 Javadoc。
【解决方案3】:

我想指出一个重要的概念,许多以前的 cmets 都提到过:

流的close() 方法不一定调用flush()

例如org.apache.axis.utils.ByteArray#close() 不会调用flush()
(点击链接查看源代码)

对于FlushableCloseable 的任何实现,更普遍的情况也是如此。一个突出的例子是java.io.PrintWriter。它的close() 方法不会调用flush()
(点击链接查看源代码)

这或许可以解释为什么开发人员在关闭他们的信息流之前会谨慎地调用flush()。我个人遇到过生产错误,其中 close() 在 PrintWriter 实例上被调用,而没有先调用 flush()

【讨论】:

  • 提供的两个示例本质上都是瘦包装类,因此它们的 flushclose 实现委托给底层流。只要任何“真实”或缓冲流在关闭时刷新。
  • 但是我意识到 Closeable.close() 的 javadoc 没有(也不能)强制执行该行为。
【解决方案4】:

已经提供的答案提供了有趣的见解,我将尝试编译 在这里。

CloseableFlushable 是两个独立的特征,Closeable 没有指定 close() 应该调用 flush()。这意味着由实现的文档(或代码)来指定是否调用flush()。在大多数情况下,这是常态,但没有保证。

现在关于@Fabian 写的内容:确实java.io.PrintWriterclose() 方法不会调用flush()。但是它调用out.close()out 是底层编写者)。假设outBufferedWriter,我们很好,因为BufferedWriter.close() 正在刷新(根据其文档)。如果是其他作家,可能就不是这样了……

所以你有两个选择:

  • 要么确保至少有一个内部 Writer/Stream 自行刷新(谨防代码重构),
  • 或者您只需致电flush(),您就一直处于安全状态。

解决方案 2,需要较少的工作,是我的首选。

【讨论】:

  • 是的,但并非所有Closable 都指定它。例如,OutputStream 没有。
猜你喜欢
  • 2015-01-08
  • 1970-01-01
  • 2023-03-18
  • 2011-01-27
  • 1970-01-01
  • 2015-10-06
  • 1970-01-01
  • 2014-12-22
  • 2010-12-24
相关资源
最近更新 更多