【问题标题】:Is flush() call necessary when using try-with-resources使用 try-with-resources 时是否需要调用 flush()
【发布时间】:2015-11-26 06:28:37
【问题描述】:

try-with-resources 会隐式调用flush() 吗?

如果是这样,在下面的代码 sn-p 中,bw.flush() 可以安全删除吗?

static void printToFile1(String text, File file) {
    try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
        bw.write(text);
        bw.flush();
    } catch (IOException ex) {
        // handle ex
    }
}

ps。 我在官方文档中没有看到任何关于它的描述:

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html

【问题讨论】:

  • 没有。但是close() 无论如何都会进行冲洗。
  • 到目前为止 5 个答案,all 引用了 javadoc。猜猜这是阅读文档的标志。
  • @ZhongYu usually这个词是否如预期的那样工作?
  • @Andreas 所有这些答案都引用了一些 Writer 类的 Javadoc。因此,他们都只回答了 OP 的第二个后续问题。只有一个答案解决第一个更一般的问题(但也没有真正回答它)。
  • @Qw3ry 你是什么意思?他们都回答了这个问题,引用Writer javadoc 说关闭自动刷新为您服务。问题完全是关于Writer,因为声明 flush()的是 Writer 类,而不是 (Auto)Closeable 接口> 方法是问题的主要主题,因此该问题没有“更一般”的答案。

标签: java try-with-resources


【解决方案1】:

我真的不明白为什么其他答案集中在BufferedWriter 而不是try-with-resources

我也找不到任何规范或提到try-with-resources 语句在Flushable 的任何对象上调用flush()

https://docs.oracle.com/javase/specs/jls/se13/html/jls-14.html#jls-14.20.3

不要依赖供应商特定实施的任何未记录/未指定的行为。

try (OutputStream o = open()) {
    //writeSome
    o.flush(); // won't hurt!
}

【讨论】:

    【解决方案2】:

    来自 Javdocs:

    try-with-resources 语句是一个 try 语句,它声明一个 或更多资源。资源是必须在之后关闭的对象 该程序已完成。 try-with-resources 语句 确保每个资源在语句结束时关闭。任何 实现java.lang.AutoCloseable 的对象,其中包括所有 实现java.io.Closeable 的对象可以用作 资源。

    BufferedWriter.close() 明确表示:

    关闭流,首先刷新它。一旦流被关闭,进一步的 write() 或 flush() 调用将导致抛出 IOException。关闭之前关闭的流没有任何效果。

    【讨论】:

      【解决方案3】:

      这种情况下要编写的最少代码量:

      try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
          bw.write("Test");
      } catch (IOException e) {
          // handle exception
      }
      

      因此,您不需要显式调用 flush 方法,因为它将由 close 方法调用,如 javadoc 中所述:

      关闭流,首先刷新它。关闭流后, 进一步的 write() 或 flush() 调用将导致 IOException 抛出。关闭之前关闭的流没有任何效果。

      此行为是从Writer 类继承的,因此除了BufferedWriter 之外,同样的行为还提供给:CharArrayWriterFilterWriterOutputStreamWriterPipedWriterPrintWriterStringWriter .

      tryWithResourcesAutoCloseable 的文档中未提供此行为,因为该行为特定于Writer 的给定实现。作为WriterextendsCloseable,退出try {}块时会调用close方法,先调用close方法 flush 如前所述。

      【讨论】:

        【解决方案4】:

        CloseableAutoCloseable 是通用接口,对刷新一无所知。所以你在他们的文档中找不到任何关于它的信息——除了一些关于释放资源的词。

        另一方面,Writer 是一个目的更明确的抽象类,它现在知道一些关于刷新的事情。方法Writer.close()的一些文档摘录:

        关闭流,先刷新

        所以 - 是的 - 当使用写入器时,close 也将始终是 flush。这基本上意味着您在尝试找出关闭的真正作用时必须查阅您正在使用的具体类的文档。

        【讨论】:

          【解决方案5】:

          引用BufferedWriter.close()的javadoc:

          关闭流,先刷新

          【讨论】:

            【解决方案6】:

            使用try-with-resource 块时资源会自动关闭。作为此过程的一部分,它还将自动调用刷新。

            正如文档中提到的 BufferedWriter 的close 方法:

            关闭流,首先刷新它。关闭流后, 进一步的 write() 或 flush() 调用将导致 IOException 扔了。

            【讨论】:

              猜你喜欢
              • 2015-05-24
              • 1970-01-01
              • 2013-07-13
              • 2017-03-17
              • 1970-01-01
              • 2017-12-04
              • 1970-01-01
              • 2023-02-06
              • 1970-01-01
              相关资源
              最近更新 更多