我可以避免这种繁琐的尝试......捕获块

Che*_*eng 18 java

通常,在处理Java IO代码时,这是我写的

    FileOutputStream out = null;
    try
    {
        out = new FileOutputStream("myfile.txt");
        // More and more code goes here...
    }
    catch (Exception e)
    {
    }
    finally 
    {
        // I put the close code in finally block, to enture the opened
        // file stream is always closed even there is exception happened.
        if (out != null) {
            // Another try catch block, troublesome.
            try {
                out.close();
            } catch (IOException ex) {
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,当我尝试关闭文件流时,我需要处理另一个try ... catch块.

看起来很麻烦:(

有什么办法可以避免吗?将close代码放在非finally块中感觉不舒服,因为其他代码引起的异常将无法调用"close".

S73*_*17H 13

在最后关闭流是非常重要的.您可以使用实用程序方法简化此过程,例如:

public static void closeStream(Closeable closeable) {
    if(null != closeable) {
      try {
        closeable.close();
      } catch(IOException ex) {
        LOG.warning("Failed to properly close closeable.", ex);
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

我认为至少记录一个流关闭失败.然后用法变为:

FileOutputStream out = null;
try
{
    out = new FileOutputStream("myfile.txt");
    // More and more code goes here...
}
catch (Exception e)
{
}
finally 
{
    closeStream(out);
}
Run Code Online (Sandbox Code Playgroud)

在Java 7中,我相信流将自动关闭,并且对这些块的需求应该是多余的.

  • +1我要做的唯一注释是我喜欢将LOG作为参数传递给closeStream(),因为日志错误应该可能在日志中与调用者相关联.不是很重要,特别是@warn,但我喜欢保持日志整洁. (2认同)

kro*_*ock 6

自动资源管理将在Java 7中出现,它将自动提供对此的处理.在此之前,对象,如OutputStream,InputStream和其他人实施Closeable,因为Java 5的,我建议你提供一个实用的方法来安全关闭这些接口.这些方法通常会占用异常,因此请确保只在忽略异常时才使用它们(例如,在finally方法中).例如:

public class IOUtils {
    public static void safeClose(Closeable c) {
        try {
            if (c != null)
                c.close();
        } catch (IOException e) {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意,该close()方法可以多次调用,如果它已经关闭,后续调用将不起作用,因此在try块的正常操作期间还提供一个关闭调用,其中不会忽略异常. 从Closeable.close文档:

如果流已经关闭,则调用此方法无效

因此,在常规代码流中关闭输出流,safeClose只有在try块中出现故障时,该方法才会执行close:

FileOutputStream out = null;
try {
    out = new FileOutputStream("myfile.txt");
    //... 
    out.close();
    out = null;
} finally {
    IOUtils.safeClose(out);
}
Run Code Online (Sandbox Code Playgroud)