PushbackReader class

 

                  see  Reader class  for descriptions of PushbackReader's inherited methods.  They are:

 

.mark( readAheadLimit )  Mark the present position in the stream.

.markSupported( ) Tell whether this stream supports the mark(...) operation.

.read( )  Read a single character, returning it in the low end two bytes of an int.

.read( char[ ] )  Read characters into a char array.

.read( char[ ], offset, len)  Read characters into a portion of a char array.

.ready( ) Tell whether this stream is ready to be read.

.reset( )  Reset the stream.

.skip( n )  Skip over n characters in the stream.

.close( ) Close the stream.

 

plus

 

.unread( int )

.unread( char[ ]  )

.unread( char[ ], offset, len )    below

 

 

  PushbackReader provides a character input stream that reads from another chained character input stream as its source, while adding the ability to push just-read characters back onto the stream, or "unread" them.  Anything pushed back does not affect the actual file from which the stream may have originated.  PushbackReader is useful for finding things in files without appearing to read them.

 

  PushbackReader has two constructors - one for when you want to push back a single character and one for when you want to push back multiple characters. i.e.

 

PushbackReader pbr = new PushbackReader( anyReaderStreamObject );     creates a pushback buffer which can push back one character. One character is also the default.  i.e.

PushbackReader pbr = new  PushbackReader(new FileReader("anyfile.txt") ); 

 

PushbackReader pbr = new PushbackReader( anyReaderStreamObject, 20 );   creates a pushback buffer which can push back twenty characters  i.e

PushbackReader pbr = new  PushbackReader(new FileReader("anyfile.txt"), 20); 

 

 You would then use regular Reader  methods to read from the stream.  i.e. continuing the above example:

 

                try {

                      while (( x = pbr.read( )) != -1 ) {

                                        // do something

                        }

                  }

                  } catch (Exception ex) { }

 

  Note that you cannot use mark(...) and reset( ) with PushbackReader.  They are not supported and always throw an IOException.  The method markSupported( ) indicates this by always returning false if invoked on a PushbackReader object.

 

  Below are descriptions of three special unread(...) methods which PushbackReader adds to those provided to it by Reader and FilterReader.  They can push back a single character, characters equal to the length of an entire array of characters, or characters equal to the length of a selected portion of an array.

 

 

void .unread( int )  method

 

  This method pushes back a single character which was just read.  The character which is actually pushed back is contained as the two low order bytes in that int character parameter.

 

  You can influence what character will be subsequently re-read from the stream by altering the contents of the int character c before the unread( c ); statement is executed. However this is not done in any examples here.

 

  The sample findBracket(...) method below accepts an already-established PushbackReader object pbr as a parameter.  It reads the associated stream.  If a left bracket character ( < ) is encountered it pushes the left bracket back into the stream and returns the PushbackReader object. The next read( ) operation on that stream will now re-read that left bracket.  If the method reads to end of stream without encountering a left bracket, it returns a null PushbackReader object.

 

import java.io.*:

 

PushbackReader findBracket( PushbackReader pbr ) {

        try {

            int x = 0;

            while (( x = pbr.read( )) != -1 ) {

                if ( x == '<' ) {

                    pbr.unread( x );

                    return pbr;

                }

            }

        } catch (Exception ex) { }

        pbr = null;

        return pbr;

}

 

 

void  .unread( char[ ] )  method

 

  This unread(...) method pushes back an array's worth of characters, meaning it pushes back a number of characters equal to the length of the array char[ ] c.  After this pushback is done, the next characters to be read from the stream will return a repeat of those characters. Since char[ ] c in the unread( c ) statement must be the same character buffer used in the original  pbr.read( c ); statement, the first character read from the stream after the pushback will be the same as the contents of c[ 0 ], the character after that will have the same value as c[ 1 ], and so on.

 

  You can influence what characters will be re-read from the stream by altering the contents of char[ ] c after the initial read(...) operation but before the unread( c ); statement is executed.

 

  Although the same char[ ] c array must be used in both the read( c) and unread( c ) statements, it does not have to be used in subsequent re-reads after the unread(...).  In other words, once the pushback is accomplished using unread( c ), any subsequent read operation on the same stream object, no matter what character array buffer is specified for it,  will correctly receive the pushed back characters from c.

 

  The sample findChar(...) method below will find a record in a file containing a key character.  It accepts an already-established PushbackReader object as a parameter and reads the associated stream.  Two additional parameters provide a specified character to watch out for ( char  s ) and a length of characters ( int  l ) to retrieve from the file with each read operation. This length could correspond to the length of fixed length records in a file, for instance.  If the specified character s is encountered anywhere within a block of characters read by the method, the method pushes that entire block back into the stream and returns the PushbackReader object. The next read(...) operation on that stream will now re-read those same characters - or the same record in other words, if the parameter length happened to represent the length of logical records in the file.  If the findChar(...) method reads to end of stream without encountering the specified character, it returns a null PushbackReader object.

 

import java.io.*:

 

public static PushbackReader  findChar( PushbackReader pbr, char s, int l ) {

    try {

        int x = 0;

        char[ ] c = new char[ l ];                                               // declare a char[ ] buffer of the correct length

        while ( (x = pbr.read( c )) != -1 ) {                                // attempt to read a record, checking for EOF

            for ( int y = 0;  y < c.length;  y++ ) {                        // search the record for the specified char

                 if (c[ y ] == s) {

                     pbr.unread( c );                                                // push back the entire record if the char is found

                     return pbr;

                  }

             }

       }

    } catch (Exception ex) { }

    pbr = null;

    return pbr;

}

 

 

void  .unread( char[ ], offset, len )  method

 

  This method is similar to the method above except that it pushes back merely a portion of the characters, namely those contained in char[ ] c starting at offset int offset for length int len.  After this method returns, the next character to be read from the stream will be the same as the value of the character at c[ off ].  The following character will have the same value as c[ off + 1 ], and so on. 

 

  If the pushed back characters of length int len are exhausted in a subsequent read operation, previously unread characters from the stream will begin to be returned, up to the whole length of char[ ] c (end of stream considerations permitting, of course).