Java Embeded Closeable Resource in Try - With Statement

144 Views Asked by At

Here's a simple code.

try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("c:\\hello.txt"))));)
        {
            writer.write("Hello");
            writer.flush();
        }

So basically FileOutputStream, OutputStreamWriter, and BufferedWriter are all closeable resources. However they are not explicitly declared as individual variables in the try-with statement. In this case, will Java automatically close all of them after execution or just BufferedWriter object?

1

There are 1 best solutions below

2
Aleksa Majkic On

The Java will close BufferedWriter, which means that it will close every stream it wraps. You could've written your code differently, like so:

try (FileOutputStream fos = new FileOutputStream(new File("c:\\hello.txt"));
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter writer = new BufferedWriter(osw)) {
    writer.write("Hello");
    writer.flush();
}

This will not change the way the try-with-resources statement works, but it might be easier to read and understand how closing works.

Here is another way of writing the above code that might help illustrate stream closing (this example is for illustration purposes only).

FileOutputStream fos = new FileOutputStream(new File("c:\\hello.txt"));
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos))) {
    writer.write("Hello");
    writer.flush();
}

In Java, if any class is closed, then they will also close the underlying streams. In the above example, BufferedWriter class is wrapped around OutputStreamWriter which wraps around FileOutputStream class. As you can see, the instance fos is never closed explicitly, but it has been closed because the BufferedWriter has been closed by the try-with-resources statement.


From java doc:

The try-with-resources statement is atry statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

The following example reads the first line from a file. It uses an instance of FileReader and BufferedReader to read data from the file. FileReader and BufferedReader are resources that must be closed after the program is finished with it:

    static String readFirstLineFromFile(String path) throws IOException {
        try (FileReader fr = new FileReader(path);
             BufferedReader br = new BufferedReader(fr)) {
            return br.readLine();
        }
    }   

In this example, the resources declared in the try-with-resources statement are a FileReader and a BufferedReader. The declaration statements of these resources appear within parentheses immediately after the try keyword. The classes FileReader and BufferedReader, in Java SE 7 and later, implement the interface java.lang.AutoCloseable. Because the FileReader and BufferedReader instances are declared in a try-with-resource statement, they will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an IOException).