This page: http://blog.ostermiller.org/convert-java-outputstream-inputstream describes how to create an InputStream from OutputStream:
new ByteArrayInputStream(out.toByteArray())
Other alternatives are to use PipedStreams and new threads which is cumbersome.
I do not like the idea of copying many megabytes to new in memory byte array. Is there a library that does this more efficiently?
EDIT:
By advice from Laurence Gonsalves, i tried PipedStreams and it turned out they are not that hard to deal with. Here's the sample code in clojure:
(defn #^PipedInputStream create-pdf-stream [pdf-info] (let [in-stream (new PipedInputStream) out-stream (PipedOutputStream. in-stream)] (.start (Thread. #(;Here you write into out-stream))) in-stream))
transferTo() Method. In Java 9 or higher, you can use the InputStream. transferTo() method to copy data from InputStream to OutputStream . This method reads all bytes from this input stream and writes the bytes to the given output stream in the original order.
Though you cannot convert an OutputStream to an InputStream, java provides a way using PipedOutputStream and PipedInputStream that you can have data written to a PipedOutputStream to become available through an associated PipedInputStream.
2. Reader to InputStream in plain Java. In this example, first, we need to read all characters from given StringReader and aggregate them in StringBuilder . Then, using ByteArrayInputStream we create an instance of InputStream that wraps bytes array taken from String .
The InputStream is used to read data from a source and the OutputStream is used for writing data to a destination.
If you don't want to copy all of the data into an in-memory buffer all at once then you're going to have to have your code that uses the OutputStream (the producer) and the code that uses the InputStream (the consumer) either alternate in the same thread, or operate concurrently in two separate threads. Having them operate in the same thread is probably much more complicated that using two separate threads, is much more error prone (you'll need to make sure that the consumer never blocks waiting for input, or you'll effectively deadlock) and would necessitate having the producer and consumer running in the same loop which seems way too tightly coupled.
So use a second thread. It really isn't that complicated. The page you linked to had reasonable example. Here's a somewhat modernized version, which also closes the streams:
try (PipedInputStream in = new PipedInputStream()) { new Thread(() -> { try (PipedOutputStream out = new PipedOutputStream(in)) { writeDataToOutputStream(out); } catch (IOException iox) { // handle IOExceptions } }).start(); processDataFromInputStream(in); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With