THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

20.5.2. Filter Streams


Filter streamsFilterInputStream, FilterOutputStream, FilterReader, and
FilterWriterhelp you chain streams to produce composite streams of greater utility. Each filter stream is
bound to another stream to which it delegates the actual input or output actions. Filter streams get their
power from the ability to filterprocesswhat they read or write, transforming the data in some way.


Filter byte streams add new constructors that accept a stream of the appropriate type (input or output) to
which to connect. Filter character streams similarly add a new constructor that accepts a character stream
of the appropriate type (reader or writer). However, many character streams already have constructors that
take another character stream, so those Reader and Writer classes can act as filters even if they do not
extend FilterReader or FilterWriter.


The following shows an input filter that converts characters to uppercase:


public class UppercaseConvertor extends FilterReader {
public UppercaseConvertor(Reader in) {
super(in);


}


public int read() throws IOException {
int c = super.read();
return (c == -1? c : Character.toUpperCase((char)c));
}


public int read(char[] buf, int offset, int count)
throws IOException
{
int nread = super.read(buf, offset, count);
int last = offset + nread;
for (int i = offset; i < last; i++)
buf[i] = Character.toUpperCase(buf[i]);
return nread;
}
}


We override each of the read methods to perform the actual read and then convert the characters to upper
case. The actual reading is done by invoking an appropriate superclass method. Note that we don't invoke
read on the stream in itselfthis would bypass any filtering performed by our superclass. Note also that we
have to watch for the end of the stream. In the case of the no-arg read this means an explicit test, but in the
array version of read, a return value of 1 will prevent the for loop from executing. In the array version of
read we also have to be careful to convert to uppercase only those characters that we stored in the buffer.


We can use our uppercase convertor as follows:


public static void main(String[] args)
throws IOException
{
StringReader src = new StringReader(args[0]);
FilterReader f = new UppercaseConvertor(src);
int c;
while ((c = f.read()) != -1)
System.out.print((char)c);
System.out.println();
}

Free download pdf