Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I avoid such cumbersome try...catch block

Tags:

java

Usually, when dealing with Java IO code, here is what I wrote

    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) {
            }
        }
    }

As you can see, while I try to close the file stream, I need to deal with another try...catch block.

Look troublesome :(

Is there any way I can avoid? I don't feel comfortable in putting the close code in non-finally block, as exception caused by other codes will make no chance for "close" being called.

like image 365
Cheok Yan Cheng Avatar asked Jul 22 '10 02:07

Cheok Yan Cheng


2 Answers

It is very important that you close streams in a finally. You can simplify this process with a utility method such as:

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

I make it a point of at least logging a stream close failure. The usage then becomes:

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

In Java 7 I believe that streams will be closed automatically and the need for such blocks should be mostly redundant.

like image 185
S73417H Avatar answered Sep 29 '22 09:09

S73417H


Automatic Resource Management is coming in Java 7 which will automatically provide handling of this. Until then, objects such as OutputStream, InputStream and others implement the Closeable interface since Java 5. I suggest you provide a utility method to safe close these. These methods generally eat exceptions so make sure that you only use them when you want to ignore exceptions (e.g. in finally method). For example:

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

Note that the close() method can be called multiple times, if it is already closed subsequent calls will have no effect, so also provide a call to close during the normal operation of the try block where an exception will not be ignored. From the Closeable.close documentation:

If the stream is already closed then invoking this method has no effect

So close the output stream in the regular flow of the code and the safeClose method will only perform close if something failed in the try block:

FileOutputStream out = null;
try {
    out = new FileOutputStream("myfile.txt");
    //... 
    out.close();
    out = null;
} finally {
    IOUtils.safeClose(out);
}
like image 35
krock Avatar answered Sep 29 '22 09:09

krock