Search code examples
javafile-iostreamresource-managementtry-finally

Closing nested Reader


When reading from a text file, one typically creates a FileReader and then nests that in a BufferedReader. Which of the two readers should I close when I'm done reading? Does it matter?

FileReader fr = null;
BufferedReader br = null;
try
{
    fr = new FileReader(fileName);
    br = new BufferedReader(fr);
    // ...
}
finally
{
    // should I close fr or br here?
}

I'm a little paranoid when it comes to exception-safety. What happens when the BufferedReader constructor throws an exception? Does it close the nested reader? Or is it guaranteed not to throw?


Solution

  • Generally, close() on the outermost stream wrapper will call close() on the wrapped streams. However, if you think it's likely that a constructor will throw an exception, make liberal use of the Closeable interface.

    FileReader fr = new FileReader(fileName);
    Closeable res = fr;
    try {
        BufferedReader br = new BufferedReader(fr);
        res = br;
    } finally {
        res.close();
    }
    

    So, even if the JVM ran out of heap space for the buffer and threw an error, you wouldn't leak a file handle.

    For Java 7 and above use try-with-resources:

    try (FileReader fr = new FileReader(fileName);
        BufferedReader br = new BufferedReader(fr)) {
      // do work
    }