In every Java implementation I see of reading from a file, I almost always see a file reader used to read line by line. My thought would be that this would be terribly inefficient because it requires a system call per line.
What I'd been doing instead is to use an input stream and grab the bytes directly. In my experiments, this is significantly faster. My test was a 1MB file.
//Stream method
try {
Long startTime = new Date().getTime();
InputStream is = new FileInputStream("test");
byte[] b = new byte[is.available()];
is.read(b);
String text = new String(b);
//System.out.println(text);
Long endTime = new Date().getTime();
System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));
}
catch (Exception e) {
e.printStackTrace();
}
//Reader method
try {
Long startTime = new Date().getTime();
BufferedReader br = new BufferedReader(new FileReader("test"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
String text = sb.toString();
Long endTime = new Date().getTime();
System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));
}
catch (Exception e) {
e.printStackTrace();
}
This gives a result of:
Text length: 1054631, Total time: 9
Text length: 1034099, Total time: 22
So, why do people use readers instead of streams?
If I have a method that takes a text file and returns a String that contains all of the text, is it necessarily better to do it using a stream?
You are comparing apples to bananas. Reading one line at a time is going to be less efficient even with a bufferedReader than grabbing data as fast as possible. Note that use of available is discouraged, as it is not accurate in all situations. I found this out myself when I started using cipher streams.
FileReader
is generally used in conjunction with a BufferedReader
because frequently it makes sense to read a file line by line, specially if the file has a well-defined record structure where each record corresponds to a line.
Also, FileReader
can simplify some of the work for dealing with character encodings and conversions, as stated in the javadocs :
Convenience class for reading character files. The constructors of this class assume that the default character encoding and the default byte-buffer size are appropriate ... FileReader is meant for reading streams of characters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With