Java ByteArrayInputStream
Jakob Jenkov |
The Java ByteArrayInputStream class, java.io.ByteArrayInputStream
, of the Java IO API
enables you to read data from byte arrays as streams of bytes. In other words, the ByteArrayInputStream class
can turn a byte array into an InputStream. The ByteArrayInputStream
class is a subclass of the InputStream
class, so you can use a ByteArrayInputStream
as
an InputStream
. The ByteArrayInputStream
also has a set of additional methods that are
specific to the ByteArrayInputStream
class. I will cover some of these methods in this tutorial.
The Java ByteArrayInputStream
can be handy if your data is stored in an array, but you have a component
that can only process it as an InputStream
. The ByteArrayInputStream
can thus
wrap the byte array, and turn it into a stream.
Create a ByteArrayInputStream
To use a Java ByteArrayInputStream
you must first create an instance of the ByteArrayInputStream
class. To the constructor you pass the byte array you want to read as an InputStream
. Here is an
example of creating a ByteArrayInputStream
instance:
byte[] bytes = ... //get byte array from somewhere. ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
This example creates a ByteArrayInputStream
which can read all bytes in the byte array passed to
its constructor.
You can also tell the ByteArrayInputStream
to only read part of the given byte array. You can pass
an extra offset and length to the constructor which specifies which section of the byte array to read. Here is
how that looks:
byte[] bytes = ... //get byte array from somewhere. int offset = 20; int length = 45; ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes, offset, length);
This example creates a ByteArrayInputStream
which will only read the bytes starting from
the byte with offset 20, and 45 bytes ahead from that.
read()
You read bytes from a Java ByteArrayInputStream
just like you would from a regular InputStream
,
via its read()
method. The read()
will return the next byte from the byte array, or
-1 if the end of the byte array (or byte array section) has been reached. Here is an example of reading bytes
from a Java ByteArrayInputStream
:
int data = byteArrayInputStream.read(); while(data != -1) { //do something with data data = byteArrayInputStream.read(); }
available()
The Java ByteArrayInputStream
available()
method tells you how many bytes are still available
in the ByteArrayInputStream
. Here is an example:
int bytesAvailable = byteArrayInputStream.available();
mark()
The mark()
method of the ByteArrayInputStream
class sets an internal mark at the current
byte position - meaning right after the previous byte read. The mark()
method takes a parameter telling
how many bytes can be read past this mark, before this mark becomes invalid. By default, if no mark has been explicitly
set, the ByteArrayInputStream
has marked position 0, or the position at the offset
passed to
its constructor. Here is an example of setting a mark
in a ByteArrayInputStream
via its mark()
method:
byte[] bytes = "abcdef".getBytes(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); int data = byteArrayInputStream.read(); // read 'a' data = byteArrayInputStream.read(); // read 'b' data = byteArrayInputStream.read(); // read 'c' byteArrayInputStream.mark(1024); // mark set before reading 'd' data = byteArrayInputStream.read(); // read 'd' data = byteArrayInputStream.read(); // read 'e' data = byteArrayInputStream.read(); // read 'f'
reset()
The reset()
method of the ByteArrayInputStream
resets how far it has read into the
byte array. The index will be reset back to the last mark set on the ByteArrayInputStream
.
By default, if no mark has been explicitly
set, the ByteArrayInputStream
has marked position 0, or the position at the offset
passed to
its constructor. Here is an example of using the ByteArrayInputStream
reset()
method:
byte[] bytes = "abcdef".getBytes(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); int data = byteArrayInputStream.read(); // read 'a' data = byteArrayInputStream.read(); // read 'b' data = byteArrayInputStream.read(); // read 'c' byteArrayInputStream.mark(1024); // mark set before reading 'd' data = byteArrayInputStream.read(); // read 'd' data = byteArrayInputStream.read(); // read 'e' data = byteArrayInputStream.read(); // read 'f' byteArrayInputStream.reset(); // reset to mark before 'd' data = byteArrayInputStream.read(); // read 'd' data = byteArrayInputStream.read(); // read 'e' data = byteArrayInputStream.read(); // read 'f'
skip()
The Java ByteArrayInputStream
skip()
method enables you to skip over a number of bytes
from the underlying byte array. You pass as parameter the number of characters you want to skip over. Here is
an example of skipping over a number of bytes using the ByteArrayInputStream
skip()
method:
byteArrayInputStream.skip(20);
Closing a ByteArrayInputStream
When you are done with a Java ByteArrayInputStream
you must close it. You close a ByteArrayInputStream
by calling the its close()
method. Here is an example of opening an
ByteArrayInputStream
, reading all data from it, and then closing it:
byte[] bytes = "abcdef".getBytes() ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); int data = byteArrayInputStream.read(); while(data != -1) { data = byteArrayInputStream.read(); } byteArrayInputStream.close();
Notice how the while
loop continues until a -1
value is read from the
ByteArrayInputStream
read()
method. After that, the while loop exits, and the
ByteArrayInputStream
close()
method is called.
The above code is not 100% robust. If an exception is thrown while reading data from the
ByteArrayInputStream
, the close()
method is never called. To make the code more robust, you
will have to use the Java try-with-resources construct.
Proper exception handling for use of Java IO classes is also explained in my tutorial on
Java IO Exception Handling.
Here is an example of closing a Java ByteArrayInputStream
using the try-with-resources construct:
try( ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("abcdef".getBytes()) ) { int data = byteArrayInputStream.read(); while(data != -1){ data = byteArrayInputStream.read(); } }
Notice how the ByteArrayInputStream
is now declared inside the parentheses after the try
keyword.
This signals to Java that this ByteArrayInputStream
is to be managed by the try-with-resources construct.
Once the executing thread exits the try
block, the byteArrayInputStream
variable is closed.
If an exception is thrown from inside the try
block, the exception is caught, the
ByteArrayInputStream
is closed, and then the exception is rethrown. You are thus guaranteed that the
ByteArrayInputStream
is closed, when used inside a try-with-resources block.
Tweet | |
Jakob Jenkov |