Java FileReader
Jakob Jenkov |
The Java FileReader class, java.io.FileReader
makes it possible to read the contents of
a file as a stream of characters. It works much like the FileInputStream
except the FileInputStream
reads bytes, whereas the FileReader
reads characters.
The FileReader
is intended to read text, in other words. One character may correspond to one or more
bytes depending on the character encoding scheme.
The Java FileReader
is a subclass of the Java Reader class, so it has
many of the same methods.
Java FileReader Example
Here is a simple Java FileReader
example:
Reader fileReader = new FileReader("c:\\data\\input-text.txt"); int data = fileReader.read(); while(data != -1) { //do something with data... doSomethingWithData(data); data = fileReader.read(); } fileReader.close();
This example first creates a FileReader
which is connected directly to the file pointed to by
the file path passed as parameter to the FileReader
constructor. Second, this example reads all
characters one char
at a time from the FileReader
. Third, the FileReader
is closed.
Note: The proper exception handling has been skipped here for the sake of clarity. To learn more about correct exception handling, go to Java IO Exception Handling.
read()
The read()
method of the Java FileReader
returns an int which contains the char value of the
character read. If the read()
method returns -1, there is no more data to read in the FileReader
, and it
can be closed. That is, -1 as int value, not -1 as byte value. There is a difference here!
Here is an example of reading characters from a Java FileReader
until there are no more characters
to read:
FileReader fileReader = new FileReader("c:\\data\\input-text.txt"); int data = fileReader.read(); while(data != -1) { data = fileReader.read(); }
This example only reads the characters from the FileReader
but does not really do anything with them.
read(char[])
The Java FileReader
also has a method that can read an array of characters instead of reading
one character at a time. Here is an example of reading multiple characters into a char
array:
FileReader fileReader = new FileReader("c:\\data\\input-text.txt"); char[] destination = new char[1024]; int charsRead = fileReader.read(destination, 0, destination.length);
This read(char[])
method takes the char
array to read the characters into as
first parameter, the offset into the array from which the characters should be written, and the
maximum length of characters to write. The read(char[])
method returns the number of characters
that was actually read into the char
array. If there are less characters in the file than
the maximum number of characters you specified, then there will be less than maximum number of characters read.
Otherwise the read(char[])
method will attempt to read maximum number of characters into the array.
Read Performance
Reading an array of characters at a time is faster than reading a single character at a time from a
Java FileReader
. The difference can easily be a factor 10 or more in performance increase,
by reading an array of characters rather than reading a single character at a time.
The exact speedup gained depends on the size of the char
array you read, and the OS, hardware etc.
of the computer you are running the code on. You should study the hard disk buffer sizes etc. of the target
system before deciding. However buffer sizes of 8KB and up will give a good speedup. However, once your char
array exceeds the capacity of the underlying OS and hardware, you won't get a bigger speedup from a bigger
char
array.
You will probably have to experiment with different byte array size and measure read performance, to find the
optimal char
array size.
Transparent Buffering via BufferedReader
You can add transparent, automatic reading and buffering of an array of bytes from a FileReader
using a Java BufferedReader . The BufferedReader
reads a chunk of chars
into a char
array from the underlying
FileReader
. You can then read
the bytes one by one from the BufferedReader
and still get a lot of the speedup that comes
from reading an array of chars
rather than one character at a time. Here is an example of wrapping a
Java FileReader
in a BufferedReader
:
Reader input = new BufferedReader( new FileReader("c:\\data\\input-file.txt"), 1024 * 1024 /* buffer size */ );
Notice, that a BufferedReader
is a Reader
subclass and can be used
in any place where an Reader
can be used.
FileReader Character Encoding
The Java FileReader
assumes that you want to decode the bytes in the file using the default character encoding
for the computer your application is running on. This may not always be what you want, and you cannot change it!
If you want to specify a different character decoding scheme, don't use a FileReader
. Use an
Java InputStreamReader on a FileInputStream
instead. The InputStreamReader
lets you specify the character encoding scheme to use when reading the bytes in the underlying file.
Closing a FileReader
When you are finished reading characters from a Java FileReader
you should remember to close it.
Closing a FileReader
is done by calling its close()
method. Here is how
closing a Java FileReader
looks:
fileReader.close();
You can also use the try-with-resources construct
introduced in Java 7. Here is how to use and close a FileReader
looks with the try-with-resources
construct:
try(FileReader fileReader = new FileReader("c:\\data\\text.txt")){ int data = fileReader.read(); while(data != -1) { System.out.print((char) data)); data = fileReader.read(); } }
Notice how there is no longer any explicit close()
method call to the FileReader
instance. The try-with-resources construct
takes care of that.
Tweet | |
Jakob Jenkov |