我应该使用close或closeQuietly来关闭输出流吗?

时间:2013-06-04 10:21:06

标签: java outputstream

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

  1. closeQuietly意味着关闭一个流,没有异常抛出。

    try {
        close(out)
    } catch(IOException e) {
    }
    
  2. 靠近

    try {
        close(out)
    } catch(IOException e) {
        throw anException;
    }
    
  3. 众所周知,输出流会在关闭时将一个/几个字符写入文件末尾,如果这些写入错误,文件也无法正确打开,如ZipoutputStream。

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

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

    很抱歉没有明确地描述这个问题。

    我的意思是如何安全地进行IO操作。如果资源的发布失败,它将让调用者知道。

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

4 个答案:

答案 0 :(得分:12)

由于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所做的。

答案 1 :(得分:3)

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

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

所以我的观点是:捕获IOException并抛出包含cause-exception的特定于应用程序的异常,例如:

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

如果你坚持不抛出异常,那么至少记录是否有ERROR状态。

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

答案 2 :(得分:0)

根据经验,我从不吞下异常,所以根据我写的代码所要求的逻辑,我可能会

  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);
    }
    
  3. 由于JDK 7已经存在,我更喜欢(如Evgeniy所述)使用try-with-resources:

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

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

答案 3 :(得分:0)

清洁代码是件好事,但在任何妥协的情况下,它可以为您提供更好的结果,如维护,调试在这种情况下,我们应该这样做。它可以以更好的方式完成,如自定义异常或使用上面建议的Java7功能,但根据我的经验,编写更多行的成本是值得的。