I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this quick tutorial, we’re going to take a look at how to convert an InputStream to a byte[] – first using plain Java, then using Guava and Commons IO.

This article is part of the “Java – Back to Basic” series here on Baeldung.

Further reading:

Introduction to Spring’s StreamUtils

Discover Spring's StreamUtils class.

Read more

Introduction to Java Serialization

We learn how to serialize and deserialize objects in Java.

Read more

Java String Conversions

Quick and practical examples focused on converting String objects to different data types in Java.

Read more

2. Convert using Plain Java

Let’s start with a Java solution focused on dealing with a fixed size stream:

@Test
public void givenUsingPlainJava_whenConvertingAnInputStreamToAByteArray_thenCorrect() 
  throws IOException {
    InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });

    byte[] targetArray = new byte[initialStream.available()];
    initialStream.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 }); // not really unknown

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int nRead;
    byte[] data = new byte[1024];
    while ((nRead = is.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }

    buffer.flush();
    byte[] byteArray = buffer.toByteArray();
}

3. 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);
}

4. 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.

And there we have it – 3 simple solutions for converting a raw input stream to a byte array.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS

newest oldest most voted
Notify of
Matthieu Wipliez
Guest

Please note that the example in “plain Java” only works in this case because the ByteArrayInputStream’s implementation of “available” will return the exact number of bytes in the byte array that’s backing it. However, in a general stream this is not the case, because most streams are actually buffered, so available only returns a subset of the total number of bytes. That’s why you should not rely on “available” but instead use a loop and rely on the number of bytes really read, as returned by read(byte[]).

Eugen Paraschiv
Guest

Hey Matthieu – nice catch, I updated the article to clearly differentiate these 2 scenarios. Cheers,
Eugen.

Octavian
Guest

One thing I find “not specified enough” is that most of these routines do not close the provided InputStream (the official javadocs included). Of course, this makes all the sense in the world since it’s not necessarily the copying routine’s responsibility to close the argument.

However, all too often I see, sprinkled through the projects I am involved with, copy-pasted snippets of code without proper resource management…

Eugen Paraschiv
Guest

Hey Octavian,
Yeah – I fully agree, not closing these kinds of low level resources leads to hard to pin-point memory leaks. These are just tests and kept simple on purposes, but yes, in production code you always need to make sure you clean these up. Cheers,
Eugen.