今天我们真的需要在 close() 之前调用 flush() 吗?
Posted
技术标签:
【中文标题】今天我们真的需要在 close() 之前调用 flush() 吗?【英文标题】:Do we really need to call flush() just before close() today? 【发布时间】:2015-01-08 01:23:37 【问题描述】:我阅读了这个问题Using flush() before close(),并且接受的答案是这仅意味着您遵循模式。
就像 BufferedWriter#close() 或 FilterOutputStream.#close() 一样,如果所有缓冲的 Stream/Writer 在我们调用 close()
时都会调用它的 flush()
并且如果我们(开发人员和将审查代码的开发人员)都知道那,我们真的还需要这个吗?如果是,是什么原因?
【问题讨论】:
IMO,你没有,但这并不意味着这是一个好主意 :-) 如果你从 Writer 或 OutputStream 实现切换,如果你不刷新那些你可能会遇到意外的行为需要它。你可能会争辩说,有一些无用的 flush()'es 是一个糟糕的 JVM 设计,那么我的回答是“也许”:-) 我们可能研究的另一件事是关于向后兼容性,如果以前版本的 JVM 在没有冲洗()。 您到底在问什么,您所链接的问题未涵盖哪些内容? @jarnbjo,我只需要知道这是否只是一项闲置的工作,除非这只是明确遵守规则? @Leo,您能否在答案中给我们举个例子,如果我们先切换到没有 muanlly flush() 的 OutputStream 会出现什么意外行为? @Jaskey 可能是在其他库中实现的其他类,这些库扩展了 OutputStream 但不遵循这种“关闭时刷新”的合同,这在任何地方都没有说明? :-) 【参考方案1】:正如 javadoc 所说,您不需要 冲洗自己。 但是,考虑到您的读者和常识,这样做仍然很好。
很少有专家熟记javadoc。
如果不查找它,我无法确定流是否会被刷新,
我可能并不孤单。
看到明确的flush()
调用就非常清楚了,
从而使代码更易于阅读。
此外,方法名称close()
没有任何关于刷新的含义。
它来自Closeable
接口,
自然地,它没有提到冲洗。
如果您在关闭之前不刷新缓冲的输出流,
尽管想冲洗它,
您将依赖可能正确或不正确的假设。
这会削弱您的实施。
您所做的任何假设, 你应该以某种方式传递给未来的维护者。 一种方法是发表评论:
// no need to flush() manually, close() will do it automatically
如果您不留下此评论, 未来的维护者可能也需要查找 javadoc, 如果像我一样,他们没有记住它。 但是,既然现在自己调用它并完成它更容易更好,你为什么还要写这样的评论。
简而言之,在关闭之前先刷新只是遵循良好的逻辑。 无需假设和第二次猜测, 也不需要让你的读者思考。
【讨论】:
还有两件事要明确。1.在close()之前只有缓冲流需要flush() 2.如果我在没有flush()的情况下close(),java.io中的每个流都不会有任何副作用( )。对吗? 1.是的,刷新是一个特定于缓冲输出的概念。另见Flushable 2.java.io
中有很多流。我必须通过所有这些来验证,我只是不明白这样做的意义。另一方面,我又添加了一个刷新的理由,请参阅我更新的答案。【参考方案2】:
对于输出,调用flush() 和close() 很重要,因为缓冲的数据可能会丢失,正如第一个答案here 所解释的那样。如果您的程序输出很小并且您的编写器很快完成,那么根据我的经验,close() 和 flush() 不会有太大区别。
对于输入,我们在系统退出前不调用close()也没关系。
【讨论】:
但是close()
已经为我们刷新了,所以这是我的问题,为什么我们需要在 close() 之前手动刷新
我以前从来没有这样做过,不知道你为什么会这样做。以上是关于今天我们真的需要在 close() 之前调用 flush() 吗?的主要内容,如果未能解决你的问题,请参考以下文章
我必须在调用* sql.Tx.Rollback()之前调用* sql.Rows.Close()吗?
为啥即使调用 Close(),等待 ManualResetEvent 的线程也会继续等待?