11

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

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

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

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

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

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

很抱歉不清楚地描述了这个问题。

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

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

4

4 回答 4

16

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

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

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

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

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

于 2013-06-04T10:24:42.077 回答
2

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

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

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

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

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

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

于 2013-06-04T10:36:40.260 回答
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);
    }
    

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

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

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

于 2013-06-04T10:46:27.130 回答
0

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

于 2013-06-04T10:46:29.340 回答