# FileReader

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`](https://jenkov.com/tutorials/java-io/fileinputstream.html) 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](https://jenkov.com/tutorials/java-io/reader.html) 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](https://jenkov.com/tutorials/java-io/io-exception-handling.html).

### 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](https://jenkov.com/tutorials/java-io/bufferedreader.html) . 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](https://jenkov.com/tutorials/java-io/inputstreamreader.html) 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](https://jenkov.com/java-exception-handling/try-with-resources.html) 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.
