1. Overview
In this quick tutorial, we’re going to take a look at how to convert an InputStream to a byte[] and ByteBuffer – first using plain Java, then using Guava and Commons IO.
This article is part of the “Java – Back to Basic” series here on Baeldung.
2. Convert to Byte Array
Let’s look at obtaining a byte array from simple input streams*.* The important aspect of a byte array is that it enables an indexed (fast) access to each 8-bit (a byte) value stored in memory. Hence, you can manipulate these bytes to control each bit. We are going to take a look at how to convert a simple input stream to a byte[] – first using plain Java, then using Guava and Apache Commons IO.
2.1. Convert Using Plain Java
Let’s start with a Java solution focused on dealing with a fixed size stream:
@Test
public void givenUsingPlainJavaOnFixedSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect()
throws IOException {
InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
byte[] targetArray = new byte[is.available()];
is.read(targetArray);
}
In the case of a buffered stream – where we’re dealing with a buffered stream and don’t know the exact size of the underlying data, we need to make the implementation more flexible:
@Test
public void givenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect()
throws IOException {
InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4, 5, 6 }); // not really known
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[4];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] targetArray = buffer.toByteArray();
}
Starting with Java 9, we can achieve the same with a dedicated readNbytes method:
@Test
public void givenUsingPlainJava9OnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect()
throws IOException {
InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4, 5, 6 });
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[4];
while ((nRead = is.readNBytes(data, 0, data.length)) != 0) {
System.out.println("here " + nRead);
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[] targetArray = buffer.toByteArray();
}
The difference between these two methods is very subtle.
The first one, read(byte[] b, int off, int len), reads up to len bytes of data from the input stream, whereas the second one, readNBytes(byte[] b, int off, int len), reads exactly the requested number of bytes.
Additionally, read returns -1 if there’s no more data available in the input stream. readNbytes, however, always returns the actual number of bytes read into the buffer.
We can also read all the bytes at once:
@Test
public void
givenUsingPlainJava9_whenConvertingAnInputStreamToAByteArray_thenCorrect()
throws IOException {
InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
byte[] data = is.readAllBytes();
}
2.2. Convert Using Guava
Let’s now look at the simple Guava based solution – using the convenient ByteStreams utility class:
@Test
public void givenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect()
throws IOException {
InputStream initialStream = ByteSource.wrap(new byte[] { 0, 1, 2 }).openStream();
byte[] targetArray = ByteStreams.toByteArray(initialStream);
}
2.3. Convert Using Commons IO
And finally – a straightforward solution using Apache Commons IO:
@Test
public void givenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect()
throws IOException {
ByteArrayInputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
byte[] targetArray = IOUtils.toByteArray(initialStream);
}
The method IOUtils.toByteArray() buffers the input internally, so there is no need to use a BufferedInputStream instance when buffering is needed.
3. Convert to ByteBuffer
Now, let’s look at obtaining a ByteBuffer from an InputStream. This is useful whenever we need to do fast and direct low-level I/O operations in memory.
Using the same approach as the above sections, we’re going to take a look at how to convert an InputStream to a ByteBuffer – first using plain Java, then using Guava and Commons IO.
3.1. Convert Using Plain Java
In the case of a byte stream – we know the exact size of the underlying data. Let’s use the ByteArrayInputStream#available method to read the byte stream into a ByteBuffer:
@Test
public void givenUsingCoreClasses_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch()
throws IOException {
byte[] input = new byte[] { 0, 1, 2 };
InputStream initialStream = new ByteArrayInputStream(input);
ByteBuffer byteBuffer = ByteBuffer.allocate(3);
while (initialStream.available() > 0) {
byteBuffer.put((byte) initialStream.read());
}
assertEquals(byteBuffer.position(), input.length);
}
3.2. Convert Using Guava
Let’s now look at a simple Guava-based solution – using the convenient ByteStreams utility class:
@Test
public void givenUsingGuava__whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch()
throws IOException {
InputStream initialStream = ByteSource
.wrap(new byte[] { 0, 1, 2 })
.openStream();
byte[] targetArray = ByteStreams.toByteArray(initialStream);
ByteBuffer bufferByte = ByteBuffer.wrap(targetArray);
while (bufferByte.hasRemaining()) {
bufferByte.get();
}
assertEquals(bufferByte.position(), targetArray.length);
}
Here we use a while loop with the method hasRemaining to show a different way to read all the bytes into the ByteBuffer. Otherwise, the assertion would fail because the ByteBuffer index position will be zero.
3.3. Convert Using Commons IO
And finally – using Apache Commons IO and the IOUtils class:
@Test
public void givenUsingCommonsIo_whenByteArrayInputStreamToAByteBuffer_thenLengthMustMatch()
throws IOException {
byte[] input = new byte[] { 0, 1, 2 };
InputStream initialStream = new ByteArrayInputStream(input);
ByteBuffer byteBuffer = ByteBuffer.allocate(3);
ReadableByteChannel channel = newChannel(initialStream);
IOUtils.readFully(channel, byteBuffer);
assertEquals(byteBuffer.position(), input.length);
}
4. Conclusion
This article illustrated various ways to convert a raw input stream to a byte array and a ByteBuffer using plain Java, Guava, and Apache Commons IO.
The implementation of all these examples can be found in our GitHub project.