Java PushbackInputStream
Jakob Jenkov |
The PushbackInputStream
is intended to be used when you parse data from an InputStream
.
Sometimes you need to read ahead a few bytes to see what is coming, before you can determine how to interpret the
current byte. The PushbackInputStream
allows you to do that. Well, actually it allows you to push
the read bytes back into the stream. These bytes will then be read again the next time you call read()
.
The Java PushbackInputStream
is a subclass of the Java InputStream so
it inherits its public methods - read()
, close()
etc. The PushbackInputStream
is similar to the Java PushbackReader, except the PushbackInputStream
reads raw bytes, and the PushbackReader
reads characters (text).
PushbackInputStream Example
Here is a simple PushbackInputStream
example:
PushbackInputStream input = new PushbackInputStream( new FileInputStream("c:\\data\\input.txt")); int data = input.read(); input.unread(data);
The call to read()
reads a byte just like from an InputStream
.
The call to unread()
pushes a byte back into the PushbackInputStream
. The next time
read()
is called the pushed back bytes will be read first. If you push back multiple bytes into
the PushbackInputStream
, the latest byte pushed back will be returned first from read()
,
just like on a stack.
Create a PushbackInputStream
To use a Java PushbackInputStream
you must first create a PushbackInputStream
instance. Here is an example of creating a Java PushbackInputStream
:
PushbackInputStream input = new PushbackInputStream( new FileInputStream("c:\\data\\input.txt"));
Notice how the PushbackInputStream
needs another InputStream as parameter
to its constructor. The PushbackInputStream
will read its bytes from this underlying InputStream
.
Setting the Push Back Limit of a PushbackInputStream
You can set the number of bytes you should be able to unread in the constructor of
the PushbackInputStream
. Here is how to set the push back limit via the
PushbackInputStream
constructor:
int pushbackLimit = 8; PushbackInputStream input = new PushbackInputStream( new FileInputStream("c:\\data\\input.txt"), pushbackLimit);
This example sets an internal buffer of 8 bytes. That means you can unread at most 8 bytes at a time, before reading them again.
Read Bytes
You read bytes from the Java PushbackInputStream
via its read()
method, just like you do
from a regular InputStream . Here is an example of reading a byte from a
PushbackInputStream
:
int aByte = pushbackInputStream.read(); while(aByte != -1) { //do something with aByte byte byteRead = (byte) aByte; aByte = pushbackInputStream.read(); }
Notice, that once the PushbackInputStream
has no more bytes to read, from its underlying
PushbackInputStream
, the read()
method will return -1.
Push a Byte Back
To push a byte back into the Java PushbackInputStream
you use the unread()
method.
Here is an example of pushing a byte back into a PushbackInputStream
:
int aByte = pushbackInputStream.read(); pushbackInputStream.unread(aByte); aByte = pushbackInputStream.read()
This example first reads a byte from the PushbackInputStream
, then pushes it back into the
PushbackInputStream
, and then reads that byte back again with the final read()
call.
Closing a PushbackInputStream
When you are finished reading bytes from a Java PushbackInputStream
you should remember to close it.
Closing a PushbackInputStream
will also close the InputStream
instance from which the
PushbackInputStream
is reading.
Closing a PushbackInputStream
is done by calling its close()
method. Here is how
closing a PushbackInputStream
looks:
pushbackInputStream.close();
You can also use the try-with-resources construct
introduced in Java 7. Here is how to use and close a PushbackInputStream
looks with the try-with-resources
construct:
InputStream inputStream = new FileInputStream("data/data.bin"); try(PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream)){ int data = pushbackInputStream.read(); while(data != -1) { byte aByte = (byte) data; data = pushbackInputStream.read(); } }
Notice how there is no longer any explicit close()
method call. The try-with-resources construct
takes care of that.
Notice also that the first FileInputStream
instance is not created inside
the try-with-resources block. That means that the try-with-resources block will not automatically close this
FileInputStream
instance. However, when the PushbackInputStream
is closed
it will also close the InputStream
instance it reads from, so the FileInputStream
instance will get closed when the PushbackInputStream
is closed.
Tweet | |
Jakob Jenkov |