【问题标题】:How many of these wrapped Java I/O objects do I have to close? [duplicate]我必须关闭多少这些包装的 Java I/O 对象? [复制]
【发布时间】:2013-09-29 11:40:58
【问题描述】:

我想将 base64 编码的数据写入文件,即时解码。我有

BufferedWriter bw = new BufferedWriter(
  new OutputStreamWriter(
    new Base64OutputStream(
      new FileOutputStream(myFile, false)));

我认为这行得通,在我的finally 块中,我调用bw.close()——即close the outermost wrapper。这是否足够,或者一些匿名中间对象会泄漏?

我尝试查看代码,但被 Sun 的 OutputStreamWriter 编码处理程序的专有实现卡住了。它似乎也没有在文档中明确说明。

【问题讨论】:

标签: java stream


【解决方案1】:

一般来说,关闭最外层的包装就足够了;每个包装器在关闭时都会关闭底层流。

可以创建一个不执行此操作的包装器,但这可能被视为错误,因为FilterOutputStream 的文档要求调用关闭"releases any system resources associated with the stream."

【讨论】:

  • 我知道 JDK 中唯一违反此规则的类是 ZipOutputStream,它需要在调用 #close() 之前单独关闭条目。
【解决方案2】:

最好的办法是关闭最外层的流对象。假设它被正确实现,这将在包装的对象上调用close(),并且关闭将沿着链传播......做正确的事情。

在输出管道的情况下,这样做实际上是重要。如果您只关闭最里面的输出流/写入器,则缓冲输出(管道中的某处)有可能无法正确写入。

【讨论】:

    【解决方案3】:

    由于BufferedWriter extends AutoClosable,您可以在Java 7 中使用try-with-resources statement 在超出范围时自动关闭资源。

    try(BufferedWriter bw = new BufferedWriter(
      new OutputStreamWriter(
        new Base64OutputStream(
          new FileOutputStream(myFile, false)));
       ) {
    
          // bw.write(); 
    
    } catch(XXXException ex) {
        // Catch Block.
    }
    

    try-with-resources 语句确保每个资源在语句结束时关闭

    此外,这样代码看起来更干净。

    【讨论】:

    • 我必须支持 Java 6,至少在可预见的未来是这样。不过,我肯定更愿意这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2012-01-13
    • 1970-01-01
    • 2013-06-04
    • 2013-10-05
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多