Ramesh
Ramesh

Reputation: 2337

closing an buffer reader is compulsory

I am trying an example from http://www.roseindia.net/java/beginners/java-read-file-line-by-line.shtml in the example the BufferReader is not closed is that necessary to close the BufferReaderor not? Please explain.

FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null)   {
    // Print the content on the console
    System.out.println (strLine);
}
//Close the input stream
in.close();

Upvotes: 0

Views: 13132

Answers (3)

Stephen C
Stephen C

Reputation: 718758

From the perspective of resource leak prevention, it is not strictly necessary to close a wrapper stream if you've also closed the stream that it wraps. However, closing the wrapped stream may result in stuff getting lost (specifically in the output case), so it is better to close (just) the wrapper, and rely on documented behavior that the closing the wrapper closes the wrapped stream too. (That is certainly true for the standard I/O wrapper classes!)


Like Peter Lawrey, I question the wisdom of relying on "Rose India" examples. For instance, this one has two more obvious mistakes in it that no half-decent Java programmer should make:

  • The stream is not closed in a finally block. If any exception is thrown between opening and closing, the in.close() statement won't be executed, and the application will leak an open file descriptor. Do that too often and your application will start throwing unexpected IOExceptions.

  • The DataInputStream in the chain serves no useful purpose. Instead, they should use fstream as the parameter for the InputStreamReader. Or better still, use FileReader.


Finally, here is a corrected version of the example:

BufferedReader br = new BufferedReader(new FileReader ("textfile.txt"));
try {
    String line;
    while ((line = br.readLine()) != null)   {
        // Print the content on the console
        System.out.println(line);
    }
} finally {
    // Close the reader stack.
    br.close();
}

or using Java 7's "try with resource":

try (BufferedReader br = new BufferedReader(new FileReader ("textfile.txt"))) {
    String line;
    while ((line = br.readLine()) != null)   {
        // Print the content on the console
        System.out.println(line);
    }
}

Upvotes: 6

user219882
user219882

Reputation: 15834

Always close streams. It's a good habit which helps you to avoid some odd behaviour. Calling close() method also calls flush() so you don't have do this manually.

The best place where to close streams is probably in a finally block. If you have it like in your example and an exception occurs before the in.close() line, the stream won't be closed.

And if you have chained streams, you can only close the last one and all before it are closed too. This means br.close() in your example - not in.close();

Example

try {
    // do something with streams
} catch (IOException e) {
    // process exception - log, wrap into your runtime, whatever you want to...
} finally {
    try {
        stream.close();
    } catch (IOException e) { 
        // error - log it at least
    } 
}

Alternatively you can use closeQuietly(java.io.InputStream) in Apache Commons library.

Upvotes: 9

Alexander Pavlov
Alexander Pavlov

Reputation: 32286

Since the underlying stream is closed, it is not absolutely necessary to close BufferedReader, even though it is a good practice to close ALL Closeables in reverse order (relative to the order they were opened in.)

Upvotes: 0

Related Questions