Also if you're using Java 7, you can use a try-with-resources statement:

try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) {
    String inLine;
    while ((inLine = r.readLine()) != null) {
        System.out.println(inLine);
    }
} catch(IOException readException) {
    readException.printStackTrace();
}           
Answer from Bugasu on Stack Overflow
Top answer
1 of 8
7

The try-with-resources Statement

The try-with-resources statement is a try 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 BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:

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

In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an IOException).

Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }
}

Source =>http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

2 of 8
2

From documentation:

The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs.

The runtime system always executes the statements within the finally block regardless of what happens within the try block. So it's the perfect place to perform cleanup.

So it means if you have some connection, stream or some other resources opened you have to be sure that they will be closed after your code block will be executed.

To avoid such ugly blocks you can use utility methods:

public void close(Closeable closeable) {
    if (closeable != null) {
        try {
            closeable.close();
        } catch (IOException ex) {
            // handle block
        }
    }
}

Since Java 8 (but it is not required) you can provide your own Exception handler with closing resource:

public void close(Closeable closeable, Consumer<? extends Throwable> handler) {
    if (closeable != null) {
        try {
            closeable.close();
        } catch (IOException ex) {
            handler.accept(ex);
        }
    }
}

Also, just for knowledge, there are two cases when finally block is not called. It means that in most cases it will be called.

🌐
GeeksforGeeks
geeksforgeeks.org › java › why-you-need-to-close-the-java-streams-in-finally-block
Why You Need to Close the Java Streams in Finally Block? - GeeksforGeeks
October 27, 2021 - // Java program to show the execution of the code // when exception is not caused import java.io.*; class GFG { public static void main(String[] args) { try { // open files System.out.println("Open files"); // do some processing int a = 45; int b = 5; int div = a / b; System.out.println("After dividing a and b ans is " + div); } catch (ArithmeticException ae) { System.out.println("exception caught"); // display exception details System.out.println(ae); } finally { System.out.println("Inside finally block"); // close the files irrespective of any exception System.out.println("Close files"); } } }
🌐
Real's HowTo
rgagnon.com › javadetails › java-0539.html
Close a stream in a try/catch block - Real's Java How-to
public static boolean compareFile(File file1, File file2) { BufferedInputStream in1 = null; BufferedInputStream in2 = null; try { in1 = new BufferedInputStream(new FileInputStream(file1)); in2 = new BufferedInputStream(new FileInputStream(file2)); boolean result = true; int i; do { i = in1.read(); result = (i == in2.read()); } while ( result && i != -1 ); return result; } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } finally { close(in1); close(in2); } return false; } private static void close( InputStream is ) { if ( is != null ) { try { is.close(); } catch ( IOException ioe ) { ioe.printStackTrace(); } } }
🌐
Blogger
javarevisited.blogspot.com › 2014 › 10 › right-way-to-close-inputstream-file-resource-in-java.html
Right way to Close InputStream and OutputStream in Java - Example
} catch (IOException ioex) { System.out.println("Failed to copy files : " + ioex.getMessage()); ioex.printStackTrace(); } As you can see, we have got rid of lot of boiler plate try-finally code. Since you can declare more than one resource inside try-with-resource block, allocate your streams, channels, and readers there. That's all on this post about right way of closing InputStream and OutputStream in Java. We have seen three examples of closing streams in Java and how combining close() call of two stream can cause resource leak in Java.
🌐
Javapractices
javapractices.com › topic › TopicAction.do
Java Practices->Always close streams
*/ public class ExerciseSerializable { public static void main(String... args) { //create a Serializable List List<String> quarks = Arrays.asList( "up", "down", "strange", "charm", "top", "bottom" ); //serialize the List //note the use of abstract base class references try{ //use buffering OutputStream file = new FileOutputStream("quarks.ser"); OutputStream buffer = new BufferedOutputStream(file); ObjectOutput output = new ObjectOutputStream(buffer); try{ output.writeObject(quarks); } finally{ output.close(); } } catch(IOException ex){ logger.log(Level.SEVERE, "Cannot perform output.", ex); }
🌐
Mike my bytes
mikemybytes.com › 2021 › 01 › 26 › closing-java-streams-with-autocloseable
Closing Java Streams with AutoCloseable | Mike my bytes
January 26, 2021 - In this post, I’d like to explain which Streams have to be closed and how the closing actually works. We will also go through some of the interesting under-documented properties of this feature. AutoCloseable interface has been introduced in Java 7 as a part of try-with-resources construct, designed for easy resource cleanup right after they are not used anymore: import java.sql.Connection; // Java < 7 Connection connection = ...; try { // do something with the connection } finally { connection.close(); // explicitely close the connection!
🌐
Baeldung
baeldung.com › home › java › java io › closing java io streams
Closing Java IO Streams | Baeldung
January 8, 2024 - In this article, we examined various strategies for closing IO streams, from traditional methods invoking the close() method in the finally blocks to more streamlined approaches offered by libraries like Apache Commons IO and the elegance of ...
Find elsewhere
Top answer
1 of 8
60

Note that the following is only applicable for Java 6 and earlier. For Java 7 and later, you should switch to using try-with-resources ... as described in other answers.

If you are trying to catch and report all exceptions at source (in Java 6 or earlier), a better solution is this:

ObjectOutputStream oos = null;
try {
   oos = new ObjectOutputStream(new FileOutputStream(file));
   oos.writeObject(shapes);
   oos.flush();
} catch (FileNotFoundException ex) {
    // complain to user
} catch (IOException ex) {
    // notify user
} finally {
    if (oos != null) {
        try {
            oos.close();
        } catch (IOException ex) {
            // ignore ... any significant errors should already have been
            // reported via an IOException from the final flush.
        }
    }
}

Notes:

  • The standard Java wrapper streams, readers and writers all propagate close and flush to their wrapped streams, etc. So you only need to close or flush the outermost wrapper.
  • The purpose of flushing explicitly at the end of the try block is so that the (real) handler for IOException gets to see any write failures1.
  • When you do a close or flush on an output stream, there is a "once in a blue moon" chance that an exception will be thrown due to disc errors or file system full. You should not squash this exception!.

If you often have to "close a possibly null stream ignoring IOExceptions", then you could write yourself a helper method like this:

public void closeQuietly(Closeable closeable) {
    if (closeable != null) {
        try {
            closeable.close();
        } catch (IOException ex) {
            // ignore
        }
    }
}

then you can replace the previous finally block with:

} finally {
    closeQuietly(oos);
}

Another answer points out that a closeQuietly method is already available in an Apache Commons library ... if you don't mind adding a dependency to your project for a 10 line method.

But be careful that you only use closeQuietly on streams where IO exceptions really are irrelevant.

UPDATE : closeQuietly is deprecated in version 2.6 of the Apache Commons API. Java 7+ try-with-resources makes it redundant.


On the issue of flush() versus close() that people were asking about in comments:

  • The standard "filter" and "buffered" output streams and writers have an API contract that states that close() causes all buffered output to be flushed. You should find that all other (standard) output classes that do output buffering will behave the same way. So, for a standard class it is redundant to call flush() immediately before close().

  • For custom and 3rd-party classes, you need to investigate (e.g. read the javadoc, look at the code), but any close() method that doesn't flush buffered data is arguably broken.

  • Finally, there is the issue of what flush() actually does. What the javadoc says is this (for OutputStream ...)

    If the intended destination of this stream is an abstraction provided by the underlying operating system, for example a file, then flushing the stream guarantees only that bytes previously written to the stream are passed to the operating system for writing; it does not guarantee that they are actually written to a physical device such as a disk drive.

    So ... if you hope / imagine that calling flush() guarantees that your data will persist, you are wrong! (If you need to do that kind of thing, look at the FileChannel.force method ...)

2 of 8
33

Current best practice for try/catch/finally involving objects that are closeable (e.g. Files) is to use Java 7's try-with-resource statement, e.g.:

try (FileReader reader = new FileReader("ex.txt")) {
    System.out.println((char)reader.read());
} catch (IOException ioe) {
    ioe.printStackTrace();
}

In this case, the FileReader is automatically closed at the end of the try statement, without the need to close it in an explicit finally block. There are a few examples here:

http://ppkwok.blogspot.com/2012/11/java-cafe-2-try-with-resources.html

The official Java description is at:

http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html

🌐
Tutorialspoint
tutorialspoint.com › java › io › inputstream_close.htm
Java - InputStream close() method
package com.tutorialspoint; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class InputStreamDemo { public static void main(String[] args) { InputStream inputStream = null; try { inputStream = new BufferedInputStream(new FileInputStream("example.txt")); int data = inputStream.read(); System.out.println("First character read: " + (char) data); } catch (IOException e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); // Manually closing the stream System.out.println("Stream closed successfully."); } } catch (IOException e) { e.printStackTrace(); } } } }
🌐
IIT Kanpur
iitk.ac.in › esc101 › 05Aug › tutorial › essential › exceptions › finally.html
The finally Block
try { ... out.close(); // don't do this; it duplicates code } catch (FileNotFoundException e) { out.close(); // don't do this; it duplicates code System.err.println("Caught: FileNotFoundException: " + e.getMessage()); throw new RuntimeException(e); } catch (IOException e) { System.err.println("Caught IOException: " + e.getMessage()); } However, this duplicates code, thus making the code difficult to read and error prone if you later modify it. For example, if you add to the try block code that can throw a new type of exception, you have to remember to close the PrintWriter within the new exception handler. Copyright 1995-2005 Sun Microsystems, Inc.
🌐
Oracle
docs.oracle.com › javase › tutorial › essential › exceptions › tryResourceClose.html
The try-with-resources Statement (The Java™ Tutorials > Essential Java Classes > Exceptions)
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). Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly.
Top answer
1 of 10
42

When closing chained streams, you only need to close the outermost stream. Any errors will be propagated up the chain and be caught.

Refer to Java I/O Streams for details.

To address the issue

However, if flush() throws a runtime exception for some reason, then out.close() will never be called.

This isn't right. After you catch and ignore that exception, execution will pick back up after the catch block and the out.close() statement will be executed.

Your colleague makes a good point about the RuntimeException. If you absolutely need the stream to be closed, you can always try to close each one individually, from the outside in, stopping at the first exception.

2 of 10
34

In the Java 7 era, try-with-resources is certainly the way to go. As mentioned in several previous answers, the close request propagates from the outermost stream to the innermost stream. So a single close is all that is required.

try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f))) {
  // do something with ois
}

There is however a problem with this pattern. The try-with-resources is not aware of the inner FileInputStream, so if the ObjectInputStream constructor throws an exception, the FileInputStream is never closed (until the garbage collector gets to it). The solution is...

try (FileInputStream fis = new FileInputStream(f); ObjectInputStream ois = new ObjectInputStream(fis)) {
  // do something with ois
}

This is not as elegant, but is more robust. Whether this is actually a problem will depend on what exceptions can be thrown during construction of the outer object(s). ObjectInputStream can throw IOException which may well get handled by an application without terminating. Many stream classes only throw unchecked exceptions, which may well result in termination of the application.

🌐
Coderanch
coderanch.com › t › 277812 › java › close-FileReader-finally-clause
close a FileReader in the finally clause (I/O and Streams forum at Coderanch)
The way the taught the same idiom in the course I took was to use a nested a try/ finally block for the business of opening and closing the streams and a try/ catch block for handling errors. Like so: Same result...