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

时间:2010-07-22 02:39:58

标签: 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) {
            }
        }
    }

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

看起来很麻烦:(

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

7 个答案:

答案 0 :(得分:13)

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

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

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

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

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

答案 1 :(得分:6)

Java 7中将出现

Automatic Resource Management,它将自动提供对此的处理。在此之前,OutputStreamInputStream等对象实现了自Java 5以来的Closeable接口。我建议您提供一种实用方法来安全地关闭它们。这些方法通常会占用异常,因此请确保只在想要忽略异常时使用它们(例如在finally方法中)。例如:

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

请注意,close()方法可以多次调用,如果它已经关闭,后续调用将无效,因此在try块的正常操作期间提供关闭调用,其中异常不会被忽略了。 From the Closeable.close documentation

  

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

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

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

答案 2 :(得分:4)

讨论

Try-catch-finally and then again a try catch

Is there a preference for nested try/catch blocks?

基本上,问题是close()例外是否值得捕捉。

答案 3 :(得分:3)

Project Lombok提供了一个@Cleanup注释,它不再需要try catch块。 Here's an example

答案 4 :(得分:1)

我倾向于使用效用函数:

public static void safeClose(OutputStream out) {
  try {
    out.close();
  } catch (Exception e) {
    // do nothing
  }
}

将代码更改为更适合:

FileOutputStream out = null;
try {
  out = new FileOutputStream("myfile.txt");
  // do stuff
} catch (Exception e) {
  // do something
} finally {
  safeClose(out);
}

至少在Java 7(希望)ARM ("Automatic Resource Management") blocks会有所帮助之前,你无法在Java中做得更好。

答案 5 :(得分:1)

编写一个类似于下面的方法;来自你最后一块的电话......

static void wrappedClose(OutputStream os) {
  if (os != null) {
    try {
      os.close();
    }
    catch (IOException ex) {
       // perhaps log something here?
    }
  }

答案 6 :(得分:0)

分开你的try / catch和try / finally块。

try
{
    FileOutputStream out = new FileOutputStream("myfile.txt");
    try
    {
        // More and more code goes here...
    }
    finally 
    {
        out.close();
    }
}
catch (Exception e)
{
    //handle all exceptions
}

外部捕获物也将捕获关闭时抛出的任何东西。

相关问题