Search this site

 Home  I/O  Buffering  Character streams  NIO intro  Buffers  Channels  Buffer performance

Search this site:
Threads Database Profiling Regular expressions Random numbers Compression Exceptions C Equivalents in Java

 What do you think of this article? Did it help you? Found a mistake? Feedback and suggestions here

Reading character streams in Java

Java InputStreams are generally designed to read "raw" byte data from a file or stream. They're not generally suitable or convenient for reading character data for a couple of reasons:

  • it would then be the coder's responsibility to convert bytes to characters correctly: depending on the character encoding, there's not always a one-to-one correspondence between a byte and a character, and in any case the correspondence depends on the encoding used;
  • it would be the coder's responsibility to deal with line breaks correctly.

Java Readers

The equivalent of a character input stream in Java is a Reader. The abstract class Reader has various concrete flavours, of which an important examples is InputStreamReader. To start pulling characters from an input stream, we use the concept of stream wrapping that we saw with input stream buffering. In other words, we wrap an InputStream in an InputStreamReader, also passing in the character encoding of the stream. To pull successive characters from the stream, we then call the Reader's read() method:

InputStream in = new FileInputStream("charfile.txt");
Reader r = new InputStreamReader(in, "US-ASCII");
int intch;
while ((intch = r.read()) != -1) {
  char ch = (char) intch;
  // ...
}

For simplicity, we've not included exception handling in the above example. Note that the Reader.read() method behaves very similary to that of InputStream: it returns the next character as an int, which we must cast to a char ourselves. This is because when the end of the stream is reached, -1 is returned just as with a InputStream.read().

Buffering with BufferedReader

In practice, it's common to further wrap an InputStreamReader in a BufferedReader to improve performance. Here is an example method to count the number of letters in an ASCII text file:

public int countASCIILetters(File f) throws IOException {
  Reader r = new BufferedReader(new InputStreamReader(
          new FileInputStream(f), "US-ASCII"));
  try {
    int count = 0;
    int intch;
    while ((intch = r.read()) != -1) {
      int ch = (char) intch;
      if (Character.isLetter(ch)) {
        count++;
      }
    }
    return count;
  } finally {
    r.close();
  }
}

On the next page, we'll look at another important feature of BufferedReader: allowing you to read a line at a time from a file or character stream.

comments powered by Disqus

Written by Neil Coffey. Copyright © Javamex UK 2012. All rights reserved.