【问题标题】:Should I use method close or closeQuietly to close an output stream?我应该使用方法 close 还是 closeQuietly 来关闭输出流?
【发布时间】:2013-05-30 16:50:47
【问题描述】:

当我们需要关闭一个输出流时,我们有两个选择。

  1. closeQuietly 意味着关闭一个流而不抛出异常。

    try {
        close(out)
    } catch(IOException e) {
    }
    
  2. 关闭

    try {
        close(out)
    } catch(IOException e) {
        throw anException;
    }
    

众所周知,输出流在关闭时会将一个/几个字符写入文件末尾,如果这些写入出错,文件也无法正确打开,例如ZipoutputStream。

如果我使用第一个,我会有一些关闭失败的风险。 如果我使用第二个,它会让我的代码不友好。

有人可以给我一些建议吗?

很抱歉您描述的不清楚。

我的意思是如何安全地进行 IO 操作。如果资源释放失败,它会通知调用者。

感谢您的所有回答。特别感谢@Don Roby 给我一个链接,其中包含@Fabian Barney 回答的最佳答案

【问题讨论】:

标签: java outputstream


【解决方案1】:

由于 Java 7 IOUtils.closeQuietly 已经过时,唯一合理的解决方案是 try-with-resources 自动关闭资源

try (InputStream is = new FileInputStream(file)) {
    ...
}

请注意,它还解决了正确打开/关闭多个资源的问题

try (InputStream is = new FileInputStream(infile); OutputStream out = new FileOutputStream(outfile)) {
   ...          
}

而且它也不会抑制 close() 可能抛出的 IOException,这正是 closeQuietly 所做的。

【讨论】:

    【解决方案2】:

    close() 的某些实现可能包含其他逻辑,例如写入最终字节或flush()'ing 数据。例如FilterOutputStream

    现在对流基于网络通道或外部 USB 驱动器的情况进行成像。两者都可能随时消失。执行 close() 时可能会发生这种情况。

    所以我的意见是:捕获 IOException 并抛出包含原因异常的特定于应用程序的异常,例如:

    } catch (IOException e)
    {
        throw new IOManagementException(e);
    }
    

    如果您坚持不抛出异常,则至少记录 ERROR 状态。

    如果不这样做,可能会导致很难分析错误报告或奇怪的行为。

    【讨论】:

    • 这是一个很好的答案,但它会让我的代码不友好。我知道另一种解决方案,它是 try {..... out.close();} catch(IOException e) {throw a exception;} 最后 {IOUtils.closeQuietly(out)}
    【解决方案3】:

    根据经验,我从不接受异常,因此根据我正在编写的代码所需的逻辑,我可能会

    1. 记录异常:

      try {
        close(out);
      } catch(IOException e) {
        // log the exception
        log.info("An error has occurred during stream closing: {}", e);
      }
      
    2. 把它包起来扔得更远

      try {
         close(out);
      } catch(IOException e) {
         throw new MyException(e);
      }
      

    由于 JDK 7 已经问世,我更喜欢(如 Evgeniy 所述)使用 try-with-resources:

    try (OutputStream out = // create output stream) {
       // do the writing
    } // at this point the stream is closed
    

    这将以适当且安全的方式关闭您正在处理的流。

    【讨论】:

      【解决方案4】:

      干净的代码是一件好事,但只要妥协它可以给你更好的结果,比如维护,在这种情况下调试我们应该这样做。可以通过更好的方式来完成,例如自定义异常或使用上面建议的 Java7 功能,但根据我的经验,多写几行的成本是值得的。

      【讨论】:

        猜你喜欢
        • 2021-02-15
        • 1970-01-01
        • 2012-06-20
        • 2013-05-23
        • 2013-02-05
        • 2010-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多