Reputation: 2337
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 BufferReader
or 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
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 IOException
s.
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
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
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 Closeable
s in reverse order (relative to the order they were opened in.)
Upvotes: 0