Do I need to close() both FileReader and BufferedReader?
no.
BufferedReader.close()
closes the stream according to javadoc for BufferedReader and InputStreamReader
as well as
FileReader.close()
does.
closing an buffer reader is compulsory
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.
Use try-with-resources or close this BufferedReader in a finally clause
You are not calling br.close()
which means risking a resource leak. In order to reliably close the BufferedReader
, you have two options:
using a finally
block:
public String loader(String FilePath) {
// initialize the reader with null
BufferedReader br = null;
String str = null;
StringBuilder strb = new StringBuilder();
try {
// really initialize it inside the try block
br = new BufferedReader(new FileReader(FilePath));
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f) {
System.out.println(FilePath + " does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
} finally {
// this block will be executed in every case, success or caught exception
if (br != null) {
// again, a resource is involved, so try-catch another time
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return strb.toString();
}
using a try
-with-resources statement:
public String loader(String FilePath) {
String str = null;
StringBuilder strb = new StringBuilder();
// the following line means the try block takes care of closing the resource
try (BufferedReader br = new BufferedReader(new FileReader(FilePath))) {
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f) {
System.out.println(FilePath + " does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
}
return strb.toString();
}
How does this FileReader get closed?
When you wrap a FileReader
(or any Reader
) with a BufferedReader
, calling .close()
on the BufferedReader
will close the wrapped/underlying FileReader
as well.
This is true of all the standard Reader, Writer, OutputStream, and InputStream classes that can be used as wrappers.
Why i always need to chain FileReader to other readers?
BufferedReader
is mainly used because it is more efficient than a FileReader
. The difference between the two is that a FileReader
is used to read characters from a file whereas BufferedReader
wraps around FileReader
and uses it to buffer the input (hence the name BufferedReader
). This leads to passing FileReader
to BufferedReader
ending up with a more efficient way of reading.
But as you asked in the question... It is perfectly fine using FileReader
as long as you are okay dealing with what it provides as functionality.
Closing a BufferedReader
If you are using java 7 or greater and your code is in try catch resource
block, then it is Auto closes
.
If in below versions you have to close with close(). For that you have to change your current way of using and get the reference.
BufferedReader & FileReader read() Performance - Large Text File
Using BufferedReader
is indeed faster than using just FileReader.
I executed your code on my machine, with the following text file https://norvig.com/big.txt (6MB).
- The initial result shows roughly the same time. About 17 seconds each.
- However, this is because
System.out.print()
is a bottleneck (within the loop). Without print, the result is 4 times faster withBufferedReader
. 200ms vs 50ms. (Compare it to 17s before)
In other words, don't use System.out.print()
when benchmarking.
Example
An improved benchmark could look like this using StringBuilder
.
File file = new File("/Users/Desktop/shakes.txt");
FileReader reader = new FileReader(file);
int ch;
StringBuilder sb = new StringBuilder();
long start = System.currentTimeMillis();
while ((ch = reader.read()) != -1) {
//System.out.print((char) ch);
sb.append((char) ch);
}
long end = System.currentTimeMillis();
System.out.println(sb);
The above code provides the same output but performs much faster. It will accurately show the difference in speed when using a BufferedReader
.
Related Topics
Difference Between @JSONignore and @JSONbackreference, @JSONmanagedreference
How to Write a Java Application That Can Update Itself at Runtime
Displaying Currency in Indian Numbering Format
What Is the Significance of Url-Pattern in Web.Xml and How to Configure Servlet
Method Chaining + Inheritance Don't Play Well Together
How to Convert a String to a Date Using Simpledateformat
Java Date Parsing with Microsecond or Nanosecond Accuracy
How to Remove Entity with Manytomany Relationship in JPA (And Corresponding Join Table Rows)
Convert Boolean to Int in Java
How to Calculate the Intersection of Two Sets
How to Handle Pop-Up in Selenium Webdriver Using Java
Log4J Redirect Stdout to Dailyrollingfileappender
Spring Boot - Inject Map from Application.Yml
What's the Difference Between <> and <? Extends Object> in Java Generics
Printing All Variables Value from a Class