There are multiple possible scenarios:

a) You have a ByteArrayOutputStream, but it was declared as OutputStream. Then you can do a cast like this:

void doSomething(OutputStream os)
{
    // fails with ClassCastException if it is not a BOS
    ByteArrayOutputStream bos = (ByteArrayOutputStream)os;
...

b) if you have any other type of output stream, it does not really make sense to convert it to a BOS. (You typically want to cast it, because you want to access the result array). So in this case you simple set up a new stream and use it.

void doSomething(OutputStream os)
{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bos.write(something);
    bos.close();
    byte[] arr = bos.toByteArray();
    // what do you want to do?
    os.write(arr); // or: bos.writeTo(os);
...

c) If you have written something to any kind of OutputStream (which you do not know what it is, for example because you get it from a servlet), there is no way to get that information back. You must not write something you need later. A solution is the answer b) where you write it in your own stream, and then you can use the array for your own purpose as well as writing it to the actual output stream.

Keep in mind ByteArrayOutputStreams keep all Data in Memory.

Answer from eckes on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › java io › convert an outputstream to a byte array in java
Convert an OutputStream to a Byte Array in Java | Baeldung
March 3, 2025 - @Test public void givenFileOutputStream_whenUsingFileUtilsToReadTheFile_thenReturnByteArray(@TempDir Path tempDir) throws IOException { String data = "Welcome to Baeldung!"; String fileName = "file.txt"; Path filePath = tempDir.resolve(fileName); try (FileOutputStream outputStream = new FileOutputStream(filePath.toFile())) { outputStream.write(data.getBytes(StandardCharsets.UTF_8)); } byte[] writtenData = FileUtils.readFileToByteArray(filePath.toFile()); String result = new String(writtenData, StandardCharsets.UTF_8); assertEquals(data, result); }
Top answer
1 of 3
27

There are multiple possible scenarios:

a) You have a ByteArrayOutputStream, but it was declared as OutputStream. Then you can do a cast like this:

void doSomething(OutputStream os)
{
    // fails with ClassCastException if it is not a BOS
    ByteArrayOutputStream bos = (ByteArrayOutputStream)os;
...

b) if you have any other type of output stream, it does not really make sense to convert it to a BOS. (You typically want to cast it, because you want to access the result array). So in this case you simple set up a new stream and use it.

void doSomething(OutputStream os)
{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bos.write(something);
    bos.close();
    byte[] arr = bos.toByteArray();
    // what do you want to do?
    os.write(arr); // or: bos.writeTo(os);
...

c) If you have written something to any kind of OutputStream (which you do not know what it is, for example because you get it from a servlet), there is no way to get that information back. You must not write something you need later. A solution is the answer b) where you write it in your own stream, and then you can use the array for your own purpose as well as writing it to the actual output stream.

Keep in mind ByteArrayOutputStreams keep all Data in Memory.

2 of 3
5

You could use the writeTo method of ByteArrayOutputStream.

ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytes = new byte[8];
bos.write(bytes);
bos.writeTo(oos);

You can create an instance of ByteArrayOutputStream. You then need to write the data to this ByteOutputStream instance and then using the writeTo method, which accepts an OutputStream, you can enable the ByteArrayOutputStream to write the output, to the instance of OutputStream which you passed as the argument.

Hope it works!

🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › io › ByteArrayOutputStream.html
ByteArrayOutputStream (Java Platform SE 8 )
March 16, 2026 - This class implements an output stream in which the data is written into a byte array. The buffer automatically grows as data is written to it. The data can be retrieved using toByteArray() and toString(). Closing a ByteArrayOutputStream has no effect.
Top answer
1 of 15
295

There seem to be many links and other such stuff, but no actual code using pipes. The advantage of using java.io.PipedInputStream and java.io.PipedOutputStream is that there is no additional consumption of memory. ByteArrayOutputStream.toByteArray() returns a copy of the original buffer, so that means that whatever you have in memory, you now have two copies of it. Then writing to an InputStream means you now have three copies of the data.

The code using lambdas (hat-tip to @John Manko from the comments):

PipedInputStream in = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(in);
// in a background thread, write the given output stream to the
// PipedOutputStream for consumption
new Thread(() -> {originalOutputStream.writeTo(out);}).start();

One thing that @John Manko noted is that in certain cases, when you don't have control of the creation of the OutputStream, you may end up in a situation where the creator may clean up the OutputStream object prematurely. If you are getting the ClosedPipeException, then you should try inverting the constructors:

PipedInputStream in = new PipedInputStream(out);
new Thread(() -> {originalOutputStream.writeTo(out);}).start();

Note you can invert the constructors for the examples below too.

Thanks also to @AlexK for correcting me with starting a Thread instead of just kicking off a Runnable.


The code using try-with-resources:

// take the copy of the stream and re-write it to an InputStream
PipedInputStream in = new PipedInputStream();
    new Thread(new Runnable() {
        public void run () {
            // try-with-resources here
            // putting the try block outside the Thread will cause the
            // PipedOutputStream resource to close before the Runnable finishes
            try (final PipedOutputStream out = new PipedOutputStream(in)) {
                // write the original OutputStream to the PipedOutputStream
                // note that in order for the below method to work, you need
                // to ensure that the data has finished writing to the
                // ByteArrayOutputStream
                originalByteArrayOutputStream.writeTo(out);
            }
            catch (IOException e) {
                // logging and exception handling should go here
            }
        }
    }).start();

The original code I wrote:

// take the copy of the stream and re-write it to an InputStream
PipedInputStream in = new PipedInputStream();
final PipedOutputStream out = new PipedOutputStream(in);
new Thread(new Runnable() {
    public void run () {
        try {
            // write the original OutputStream to the PipedOutputStream
            // note that in order for the below method to work, you need
            // to ensure that the data has finished writing to the
            // ByteArrayOutputStream
            originalByteArrayOutputStream.writeTo(out);
        }
        catch (IOException e) {
            // logging and exception handling should go here
        }
        finally {
            // close the PipedOutputStream here because we're done writing data
            // once this thread has completed its run
            if (out != null) {
                // close the PipedOutputStream cleanly
                out.close();
            }
        }   
    }
}).start();

This code assumes that the originalByteArrayOutputStream is a ByteArrayOutputStream as it is usually the only usable output stream, unless you're writing to a file. The great thing about this is that since it's in a separate thread, it also is working in parallel, so whatever is consuming your input stream will be streaming out of your old output stream too. That is beneficial because the buffer can remain smaller and you'll have less latency and less memory usage.

If you don't have a ByteArrayOutputStream, then instead of using writeTo(), you will have to use one of the write() methods in the java.io.OutputStream class or one of the other methods available in a subclass.

2 of 15
123

An OutputStream is one where you write data to. If some module exposes an OutputStream, the expectation is that there is something reading at the other end.

Something that exposes an InputStream, on the other hand, is indicating that you will need to listen to this stream, and there will be data that you can read.

So it is possible to connect an InputStream to an OutputStream

InputStream----read---> intermediateBytes[n] ----write----> OutputStream

As someone metioned, this is what the copy() method from IOUtils lets you do. It does not make sense to go the other way... hopefully this makes some sense

UPDATE:

Of course the more I think of this, the more I can see how this actually would be a requirement. I know some of the comments mentioned Piped input/ouput streams, but there is another possibility.

If the output stream that is exposed is a ByteArrayOutputStream, then you can always get the full contents by calling the toByteArray() method. Then you can create an input stream wrapper by using the ByteArrayInputStream sub-class. These two are pseudo-streams, they both basically just wrap an array of bytes. Using the streams this way, therefore, is technically possible, but to me it is still very strange...

🌐
Coderanch
coderanch.com › t › 620606 › java › Convert-OutputStream-byte
Convert OutputStream to byte[] (I/O and Streams forum at Coderanch)
September 24, 2013 - This is the scenario, I am using lowagie librarie to generate pdf, for that, I have to pass an outputstream to it, but I dont want to save the file in the server machine, I want to provide it for instant download, that is why I am trying to convert the outputstream to a byte array. This is the workaround along with my try: with that kind of file.toString I am receiving the file broken, I want to know if there is a better way. ... As has already been suggested, just replace with and replace with You can then get the byte array from the ByteArrayOutputStream .
🌐
Baeldung
baeldung.com › home › java › java io › convert an outputstream to an inputstream
Convert an OutputStream to an InputStream | Baeldung
December 7, 2023 - Next, we can write the given OutputStream‘s data to the PipedOutputStream. Then, on the other side, we can read the data from the PipedInputStream. ... @Test void whenUsingPipeStream_thenGetExpectedInputStream() throws IOException { String content = "I'm going through the pipe."; ByteArrayOutputStream originOut = new ByteArrayOutputStream(); originOut.write(content.getBytes()); //connect the pipe PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(in); try (in) { new Thread(() -> { try (out) { originOut.writeTo(out); } catch (IOException iox) { // ...
Top answer
1 of 2
7

From a theoretical perspective (i.e., irrespective of whether it makes sense in practice as a use case), this is an interesting question that essentially requires the implementation of a method like

public abstract byte[] convert(OutputStream out);

The Java OutputStream class, as its name implies, only supports an overridden write() method for I/O, and that write() method gets either an integer (representing 1 byte) or a byte array, the contents of which it sends to an output (e.g., a file).

For example, the following code saves the bytes already present in the data array, to the output.txt file:

byte[] data = ... // Get some data
OutputStream fos = new FileOutputStream("path/to/output.txt");
fos.write(data);

In order to get all the data that a given OutputStream will be outputting and put it into a byte array (i.e., into a byte[] object), the class from which the corresponding OutputStream object was instantiated, should keep storing all the bytes processed via its write() methods and provide a special method, such as toByteArray(), that would return them all, upon invocation.

This is exactly what the ByteArrayOutputStream class does, making the convert() method trivial (and unnecessary):

public byte[] convert(ByteArrayOutputStream out) {
  return out.toByteArray();
}

For any other type of OutputStream, not inherently supporting a similar conversion to a byte[] object, there is no way to make the conversion, before the OutputStream is drained, i.e. before the desired calls to its write() methods have been completed.

If such an assumption (of the writes to have been completed) can be made, and if the original OutputStream object can be replaced, then one option is to wrap it inside a delegate class that would essentially "grab" the bytes that would be supplied via its write() methods. For example:

public class DrainableOutputStream extends FilterOutputStream {
  private final ByteArrayOutputStream buffer;
  public DrainableOutputStream(OutputStream out) {
    super(out);
    this.buffer = new ByteArrayOutputStream();
  }
  @Override
  public void write(byte b[]) throws IOException {
    this.buffer.write(b);
    super.write(b);
  }
  @Override
  public void write(byte b[], int off, int len) throws IOException {
    this.buffer.write(b, off, len);
    super.write(b, off, len);
  }
  @Override
  public void write(int b) throws IOException {
    this.buffer.write(b);    
    super.write(b);
  }
  public byte[] toByteArray() {
    return this.buffer.toByteArray();
  }
}

The calls to the write() methods of the internal "buffer" (ByteArrayOutputStream) precede the calls to the original stream (which, in turn, can be accessed via super, or even via this.out, since the corresponding parameter of the FilterOutputStream is protected). This makes sure that the bytes will be buffered, even if there is an exception while writing to the original stream.

To reduce the overhead, the calls to super in the above class can be omitted - e.g., if only the "conversion" to a byte array is desired. Even the ByteArrayOutputStream or OutputStream classes can be used as parent classes, with a bit more work and some assumptions (e.g., about the reset() method).

In any case, enough memory has to be available for the draining to take place and for the toByteArray() method to work.

2 of 2
6

For @Obicere comment example:

ByteArrayOutputStream btOs = new ByteArrayOutputStream();
btOs.write("test bytes".getBytes());    
String restoredString = new String(btOs.toByteArray());
System.out.println(restoredString);
Find elsewhere
🌐
Bureau of Economic Geology
beg.utexas.edu › lmod › agi.servlet › doc › detail › java › io › ByteArrayOutputStream.html
java.io Class ByteArrayOutputStream
public class ByteArrayOutputStream · extends OutputStream · This class implements an output stream in which the data is written into a byte array. The buffer automatically grows as data is written to it. The data can be retrieved using toByteArray() and toString().
🌐
How to do in Java
howtodoinjava.com › home › i/o › converting outputstream to inputstream
Converting OutputStream to InputStream - HowToDoInJava
April 21, 2022 - //OutputStream ByteArrayOutputStream outStream = new ByteArrayOutputStream(new File("path/file")); //byte[] -> InputStream ByteArrayInputStream inStream = new ByteArrayInputStream( outStream.toByteArray() ) This is the simplest way to convert ...
🌐
Jenkov
jenkov.com › tutorials › java-io › bytearrayoutputstream.html
Java ByteArrayOutputStream
The the Java OutputStream Tutorial for more information about how to write bytes to an OutputStream. Once you have finished writing to the ByteArrayOutputStream you can obtain all the bytes written as a Java byte array, using the ByteArrayOutputStream toByteArray() method.
🌐
Vultr Docs
docs.vultr.com › java › examples › convert-the-inputstream-into-byte-array
Java Program to Convert the InputStream into Byte Array | Vultr Docs
December 19, 2024 - This method reads bytes from an InputStream into a buffer, then writes them into a ByteArrayOutputStream. By repeatedly reading and writing, it captures all data from the InputStream.
🌐
Quora
quora.com › What-is-the-difference-between-the-ByteArrayOutputStream-and-BufferedOutputStream-in-Java
What is the difference between the ByteArrayOutputStream and BufferedOutputStream in Java? - Quora
Improves performance for many small writes to a non-memory OutputStream by batching writes into larger chunks (reduces system calls, network sends). Performance depends on buffer size relative to write patterns; too-small buffers give less benefit, too-large buffers waste memory. ... ByteArrayOutputStream: memory usage equals stored bytes plus expansion overhead; retained until object is GC’d or you extract and discard the array.
🌐
Oracle
docs.oracle.com › en › java › javase › 22 › docs › api › java.base › java › io › ByteArrayOutputStream.html
ByteArrayOutputStream (Java SE 22 & JDK 22)
July 16, 2024 - Writes the specified byte to this ByteArrayOutputStream. Specified by: write in class OutputStream · Parameters: b - the byte to be written. public void write · (byte[] b, int off, int len) Writes len bytes from the specified byte array starting at offset off to this ByteArrayOutputStream.
🌐
Programiz
programiz.com › java-programming › bytearrayoutputstream
Java ByteArrayOutputStream (With Examples)
// Creating a ByteArrayOutputStream with specified size ByteArrayOutputStream out = new ByteArrayOutputStream(int size); Here, the size specifies the length of the array. The ByteArrayOutputStream class provides the implementation of the different methods present in the OutputStream class.
🌐
Apache Commons
commons.apache.org › proper › commons-io › javadocs › api-2.5 › org › apache › commons › io › output › ByteArrayOutputStream.html
ByteArrayOutputStream (Apache Commons IO 2.5 API)
public ByteArrayOutputStream(int size) Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes. Parameters: size - the initial size · Throws: IllegalArgumentException - if size is negative · public void write(byte[] b, int off, int len) Write the bytes ...
🌐
Codemia
codemia.io › knowledge-hub › path › how_do_i_convert_an_outputstream_to_an_inputstream
How do I convert an OutputStream to an InputStream?
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises
🌐
Coderanch
coderanch.com › t › 693112 › java › Writing-byte-array-outputstream
Writing a byte-array into an outputstream (I/O and Streams forum at Coderanch)
April 19, 2018 - have to use a ByteArrayOutputStream to get the byte-array into an outputstream. Not true. Many output classes have write methods that write bytes from an array. Look at the API doc.