THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

20.5.11. Pushback Streams


A Pushback stream lets you push back, or "unread," characters or bytes when you have read too far.
Pushback is typically useful for breaking input into tokens. Lexical scanners, for example, often know that a
token (such as an identifier) has ended only when they have read the first character that follows it. Having
seen that character, the scanner must push it back onto the input stream so that it is available as the start of the
next token. The following example uses PushbackInputStream to report the longest consecutive
sequence of any single byte in its input:


import java.io.*;


class SequenceCount {
public static void main(String[] args)
throws IOException
{
PushbackInputStream
in = new PushbackInputStream(System.in);
int max = 0; // longest sequence found
int maxB = -1; // the byte in that sequence
int b; // current byte in input


do {
int cnt;
int b1 = in.read(); // 1st byte in sequence
for (cnt = 1; (b = in.read()) == b1; cnt++)
continue;
if (cnt > max) {
max = cnt; // remember length
maxB = b1; // remember which byte value
}
in.unread(b); // pushback start of next seq
} while (b != -1); // until we hit end of input


System.out.println(max + " bytes of " + maxB);
}
}


We know that we have reached the end of one sequence only when we read the first byte of the next sequence.
We push this byte back using unread so that it is read again when we repeat the do loop for the next
sequence.


Both PushbackInputStream and PushbackReader support two constructors: One takes a reference to
the wrapped stream and the size of the pushback buffer to create, while the other only takes a reference to the
wrapped stream and uses a pushback buffer with space for one piece of data (byte or char as appropriate).
Attempting to push back more than the specified amount of data will cause an IOException.


Each Pushback stream has three variants of unread, matching the variants of read. We illustrate the
character version of PushbackReader, but the byte equivalents for PushbackInputStream have the
same behavior:


public voidunread(int c)tHRows IOException

Pushes back the single character c. If there is insufficient room in the
pushback buffer an IOException is thrown.

public voidunread(char[] buf, int offset, int count)throws
IOException
Free download pdf