Wil Boayue

Software Engineer/Architect

Java Automatic Resource Management

You might have seen this example from The Java Tutorials.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    public class CopyBytes {
        public static void main(String[] args) throws IOException {

            FileInputStream in = null;
            FileOutputStream out = null;

            try {
                in = new FileInputStream("xanadu.txt");
                out = new FileOutputStream("outagain.txt");
                int c;

                while ((c = in.read()) != -1) {
                    out.write(c);
                }
            } finally {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            }
        }
    }

Unfortunately, this code has a bug. If an exception is thrown while closing the input stream on line #21, the output stream will not be closed on line #24.

Prior to Java 7 a clean version of this could be written with the Commons IO: IOUtils or Google Guava: Closer utility classes.

The following is a correct implementation using Google Guava.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    public class CopyBytes {
        public static void main(String[] args) throws IOException {

            Closer closer = Closer.create();

            try {
                InputStream in = closer.register(new FileInputStream("xanadu.txt"));
                OutputStream out = closer.register(new FileOutputStream("outagain.txt"));

                int c;

                while ((c = in.read()) != -1) {
                    out.write(c);
                }
            } catch (Throwable e) {
              throw closer.rethrow(e);
            } finally {
              closer.close();
            }
        }
    }

Language support for managing the common pattern makes it even easier in Java 7.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public class CopyBytes {
        public static void main(String[] args) throws IOException {
            try (
              FileInputStream in = new FileInputStream("xanadu.txt");
              FileOutputStream out = new FileOutputStream("outagain.txt");

            ) {
                int c;

                while ((c = in.read()) != -1) {
                    out.write(c);
                }
            }
        }
    }

Get the details in this article

Comments