|Lesson 6|| Marking and resetting|
|Objective|| Learn how to mark and reset a Stream.|
Mark and reset a Stream in Java
It is often useful to be able to read a few bytes, and then back up and reread them. For example, in a Java compiler you do not know for sure whether you are reading the token
, or <<=
until you have read one too many characters.
It would be useful to be able to back up and reread the token once you know which token you have read.
Compiler design and other parsing problems provide many more examples, but this need occurs elsewhere as well.
Some, but not all, input streams allow you to mark a particular position in the stream and then return to it.
mark() , reset(), and markSupported() methods
in the java.io.InputStream
class determine this.
There can be only one mark in the stream at any given time. Marking a second location erases the first mark. If marking is not supported, the
reset() methods throw IOExceptions.
The only two input stream classes in java.io that always support marking are BufferedInputStream and ByteArrayInputStream.
However, other input streams like DataInputStream support marking when they're chained to a buffered input stream first.
The buffer and the current state of the buffer are stored in protected fields.
The buffer itself is a byte array called
buf; the number of bytes in the buffer is an
int named count;
the index of the next byte that will be returned by
read() is an int called pos; the mark, if any, is an int called
the read-ahead limit before the mark is invalidated is an
Subclasses of BufferedInputStream can directly access all these fields, which can be important for performance.
protected byte buf
protected int count
protected int pos
protected int markpos
protected int marklimit
BufferedInputStream only overrides methods from InputStream and does not declare any new methods of its own. Marking and resetting are supported.
public synchronized int read() throws IOException
public synchronized int read(byte data, int offset, int length)
public synchronized long skip(long n) throws IOException
public synchronized int available() throws IOException
public synchronized void mark(int readLimit)
public synchronized void reset() throws IOException
public boolean markSupported()
In Java 2 and later, the two multibyte
read() methods try to fill the specified array or subarray completely by reading repeatedly from the underlying input stream. They return only when the requested number of bytes have been read, the end of stream is reached, or the underlying stream would block.
This is not the case for most input streams (including buffered input streams in Java 1.1.x and earlier), which only attempt one read from the underlying stream or data source before returning.