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.

Answer from mikeho on Stack Overflow
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...

🌐
Baeldung
baeldung.com › home › java › java io › convert an outputstream to an inputstream
Convert an OutputStream to an InputStream | Baeldung
December 7, 2023 - Explore two approaches to converting an OutputStream to an InputStream: using a byte array and a pipe.
Discussions

io - Easy way to write contents of a Java InputStream to an OutputStream - Stack Overflow
I was surprised to find today that I couldn't track down any simple way to write the contents of an InputStream to an OutputStream in Java. Obviously, the byte buffer code isn't difficult to write,... More on stackoverflow.com
🌐 stackoverflow.com
Converting an output stream to an input stream - Free Support Forum - aspose.com
Hello,I would like to know if there is any problems in chaining output streams to input streams of aspose manipulated edited pdf documents in pdf kit for java. Say I wish to save a resultant pdf file of a form save operation and then convert this output stream to an input steam and use this ... More on forum.aspose.com
🌐 forum.aspose.com
1
0
February 3, 2009
New method in JDK 9: InputStream.transferTo(OutputStream)
It's blocking, in case you were wondering: This method may block indefinitely reading from the input stream, or writing to the output stream. The behavior for the case where the input and/or output stream is asynchronously closed More on reddit.com
🌐 r/java
16
105
August 13, 2017
Transferring InputStream to OutputStream in JDK 9
There is no need to make AutoCloables declared in a try-with-resources block final. They are implicitly final. More on reddit.com
🌐 r/java
12
24
January 31, 2018
🌐
Coderanch
coderanch.com › t › 551299 › java › output-stream-input-stream
output stream to input stream (Java in General forum at Coderanch)
Perhaps you should look into java.io.PipedOutputStream and PipedInputStream. Bill ... I think Piped streams are for concurrent operations using threads. But, in my requirement those are one after another. ... So you're saying you need to write everything to the OutputStream first, and only then use the InputStream...
🌐
How to do in Java
howtodoinjava.com › home › i/o › converting outputstream to inputstream
Converting OutputStream to InputStream - HowToDoInJava
April 21, 2022 - Learn to convert OutputStream to InputStream in Java using ByteArrayInputStream and Java NIO Files Channel API.
🌐
Whitfin
whitfin.io › blog › redirecting-inputstream-outputstream-java
Whitfin's Blog: Redirecting An InputStream To An OutputStream In Java
May 11, 2014 - What I'm going to show you is a way to redirect the output to an OutputStream without the necessity of synchronous execution. Obviously, you could implement a simple Thread model for your code, but it'd be nicer to have something exist for doing so already. Consider the class below: Now, the idea of the above is to create a new Thread to associate an InputStream to an OutputStream (both passed in), in order to continually read the InputStream, without holding up execution.
🌐
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
Find elsewhere
🌐
Baeldung
baeldung.com › home › java › java io › easy ways to write a java inputstream to an outputstream
Easy Ways to Write a Java InputStream to an OutputStream | Baeldung
January 18, 2024 - void copy(InputStream source, OutputStream target) throws IOException { byte[] buf = new byte[8192]; int length; while ((length = source.read(buf)) != -1) { target.write(buf, 0, length); } } This code is pretty straightforward — we’re simply reading in some bytes and then writing them out. Java 9 provides a utility method, InputStream.transferTo(), for this task.
🌐
Stephen Ostermiller
blog.ostermiller.org › home › convert a java outputstream to an inputstream
Convert a Java OutputStream to an InputStream - Stephen Ostermiller
September 9, 2019 - The easiest method is to buffer the data using a byte array. The code will look something like this: ByteArrayOutputStream out = new ByteArrayOutputStream(); class1.putDataOnOutputStream(out); class2.processDataFromInputStream( new ByteArrayInputStream(out.toByteArray()) ); That's it!
🌐
Attacomsian
attacomsian.com › blog › java-convert-inputstream-to-outputstream
How to convert InputStream to OutputStream in Java
October 29, 2022 - try (InputStream in = Files.newInputStream(Paths.get("input.txt")); OutputStream out = Files.newOutputStream(Paths.get("output.txt"))) { // convert input stream to output stream long length = in.transferTo(out); System.out.println("Bytes transferred: " + length); } catch (IOException ex) { ex.printStackTrace(); } In Java 8 or below, you can manually copy data from an InputStream to an OutputStream object as shown below:
🌐
Aspose
forum.aspose.com › aspose.pdf product family
Converting an output stream to an input stream - Free Support Forum - aspose.com
February 3, 2009 - Say I wish to save a resultant ... use this as a source document in new operation like 1. save (inputstream1, finalOutputStream) inputstream2 = finalOutputStream 2. inputstream2 = finalOutputStream can just keep a saved ...
🌐
How to do in Java
howtodoinjava.com › home › i/o › convert inputstream to outputstream in java
Convert InputStream to OutputStream in Java
April 24, 2022 - There is no API similar to transferTo() in Java 8. So we can mimic the logic written in the above API’s source code and write it ourselves. void copy(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[8192]; int length; while ((length = in.read(buf)) > 0) { out.write(buf, 0, length); } }
🌐
SourceForge
io-tools.sourceforge.net › easystream › OutputStream_to_InputStream.html
[io-tools] – Convert an OutputStream in an InputStream (or a Writer into a Reader)
May 29, 2016 - A Java Open Source library, that contains a set of utilities for streams. 'Convert' OutputStream into InputStream, statistics, debugging.
🌐
DZone
dzone.com › coding › java › transferring inputstream to outputstream in jdk 9
Transferring InputStream to OutputStream in JDK 9 - Java
February 1, 2018 - This method, as its name suggests, allows for the easy transfer (copy) of bytes from the input stream represented by the object the method is called upon to the output stream provided to that method.
🌐
Coderanch
coderanch.com › t › 422850 › java › Converting-outputstream-inputstream
Converting outputstream to inputstream (I/O and Streams forum at Coderanch)
March 10, 2009 - I have tried using PipedInputStream/PipedOutputStream but the performance is much slower. Some googling seems to reveal that this may be caused by the limited buffer size on these objects as well as the synchronization of threads that is required. Does anyone have a suggestion for a performance way to go from an output stream to an inputstream.
🌐
Google Groups
groups.google.com › g › clojure › c › BZxYCQQJtV8
How to: convert output stream into an input stream
December 15, 2011 - You can probably consider PipedOutputStream and PipedInputStream: http://docs.oracle.com/javase/6/docs/api/java/io/PipedOutputStream.html http://docs.oracle.com/javase/6/docs/api/java/io/PipedInputStream.html
🌐
GeeksforGeeks
geeksforgeeks.org › java › difference-between-inputstream-and-outputstream-in-java
Difference Between InputStream and OutputStream in Java - GeeksforGeeks
January 28, 2021 - Thus, InputStream read data from source one item at a time. 1.2 OutputStream: OutputStream is an abstract class of Byte Stream that describes stream output and it is used for writing data to a file, image, audio, etc. Thus, OutputStream writes data to the destination one at a time. In this Program, the file gfg.txt consist of “GEEKSFORGEEKS”. Note: In the file is saved in the same location where java ...
🌐
amitph
amitph.com › home › java › how to write inputstream to outputstream in java
How to Write InputStream to OutputStream in Java - amitph
January 15, 2025 - Alternatively, Java provides a concise abstraction to achieve this. Using the transferTo method on the InputStream we can avoid buffers and iteration logic. Next is example of writing to OutputStream.
🌐
SAP Community
community.sap.com › t5 › technology-q-a › java-convert-outputstream-to-inputstream › qaq-p › 2770658
JAVA Convert OutputStream to InputStream - SAP Community
October 2, 2007 - You could either use a ByteArrayInputStream and ByteArrayOutputStream to convert between the two. Otherwise use PipedInputStream and PipedOutputStream to do the conversion.