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 #17, the output stream will not be closed on line #20.

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