在 Java 中关闭 OutputStream 的正确方法? [复制]

Posted

技术标签:

【中文标题】在 Java 中关闭 OutputStream 的正确方法? [复制]【英文标题】:Proper way to close an OutputStream in Java? [duplicate] 【发布时间】:2011-06-07 17:17:44 【问题描述】:

这几乎看起来很傻,但是关闭 OutputStream 时最可靠的模式是什么?现在我有类似下面的东西,这似乎是 try-catch-finally-overkill:

private void writeContentsToFile(OutputStream ostream, Properties contents) 
    try 
        contents.store(ostream, "comments");
    
    catch (IOException e) 
        throw new ResourceException("Failed to write contents", e);
    
    finally 
        try 
            ostream.close();
        
        catch (IOException e)  /* what can be done here anyway? */ 
    

为什么 close 抛出一个检查异常对我来说仍然是一个谜。我可以创建执行 close/catch 块的包装器方法,但如果已经有像 FileUtil.closeFileAndThrowUncheckedException() 这样的东西,我想使用它。当您有很多具有大量开发人员的小型项目时,这会变得更加有用;一种正确的方法。

【问题讨论】:

close() 可能会写入数据。如果例如底层流缓冲数据,close() 将刷新数据 - 这可能会由于写入调用可能失败的原因而失败。(在例如套接字的情况下,close() 可能会发出来自先前之一的失败信号也写电话) 考虑使用 Writer 而不是直接使用流。如果您使用为任务量身定制的作家,作家会提供很多便利。例如,当使用BufferedWriter 存储您的属性时将是一个不错的选择。如果您查看源代码,您会看到它会刷新并关闭流,但您仍然需要处理“额外的”IOException。 @Paul:我通常会这样做,但我在这种情况下使用了 OutputStream 作为一个简单的例子。 在您的最后一次捕获中,您可以throw new RuntimeException(e)。未选中,您不会隐藏异常。 @Raedwald,我已将此问题标记为重新打开。虽然它确实是重复的,但它现在是谷歌上最明显的搜索结果(我不会在这里添加搜索词,否则会加强效果)。答案也很明显已经过时了。我认为应该重新打开这个问题并发布正确答案。 【参考方案1】:

如果您使用的是 Apache Commons,那么 IOUtils.closeQuietly() 可以很好地完成这项工作。见http://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.OutputStream)

【讨论】:

我怎么会错过呢?我以为我浏览了 IOUtils。我会给这个问题一些时间以获得更多反馈,但这看起来很正确。 当我用来实现这个时,我通常会用 RuntimeException 包装 IOException 并再次抛出它,但 closeQuietly 实际上是在吞下异常。哪个更好?【参考方案2】:

我认为不应该吞下异常。调用者被误导认为内容已成功写入。异常应该向上传播。

如果您不喜欢已检查的异常(尤其是对于此类低级错误),请将其包装为未检查。或者您可以遵循 Java 的约定,无论好坏,并在您的方法上声明 IOException。

【讨论】:

【参考方案3】:

我认为你的方式是“最好的”方式。如果 close 抛出异常,那么您确实无能为力。这可能会引发捕获的异常,因为它可能很糟糕,具体取决于它的使用方式。如果你真的需要关闭一个文件,你想强制执行它。如果您只想使用 close 进行错误处理,您应该忽略异常。

【讨论】:

以上是关于在 Java 中关闭 OutputStream 的正确方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

检查在java中关闭的游标

java中的io流都有哪些

在 Java 中关闭数据库连接

我需要在 Java 中关闭 InputStream 吗?

在 Java Swing 中关闭数据库连接

如何让线程等待 JFrame 在 Java 中关闭?