How to Convert OutputStream to InputStream

Sometime we need to convert Output Stream to Input Stream. We can perform the conversion multiple ways. 

The following two approaches are most popular:

1. ByteArrayOutputStream to ByteArrayInputStream

2. PipedOutputStream to PipedInputStream

Complete example code is available in the [Github].

Approach 1: ByteArrayOutputStream/ByteArrayInputStream

The ByteArrayOutputStream/ByteArrayInputStream is the easiest way to convert OutputStream to InputStream.

Code snippet:

TextWriter textWriterBins = new TextWriter();

ByteArrayOutputStream bouts = new ByteArrayOutputStream();

textWriterBins.write(bouts);

ByteArrayInputStream bins = new ByteArrayInputStream(bouts.toByteArray());

TextReader textReader = new TextReader(bins);

textReader.print();


Here, TextWriter is a class which writes some text in the OutputStream and TextReader is a class which reads data from InputStream and print on the console.

In the above code snippet, the TextWriter.write method writes the data in the ByteArrayOutputStream. Now, the ByteArrayInputStream is created by ByteArrayOutputStream and passed to the TextReader to print the data from InputStream.

It is simplest solution to convert OutputStream to InputStream but the data is hold in memory. This approach is not memory efficient solution for large amount of data. If we need to convert large data from OutputStream to InputStream then we have to used PipeOutputStream/PipedInputStream. 

Approach 2: PipeOutputStream/PipedInputStream

The PipeOutputStream/PipedInputStream is the little complex than the Approach 1. However, if we want to convert large data from output stream to input stream than this approach is the most efficient approach.

However, PipeOutputStream/PipedInputStream cannot be used in the single thread environment. We have to run PipedOutputStream in the new Thread and PipedInputStream will be run in the main Thread.

The coding technique will be cleared, if we look at the following example:

At first, we need to define the PipedOutputStream and PipedInputStream objects:
PipedOutputStream pipedOut = new PipedOutputStream();
PipedInputStream pipedIS = new PipedInputStream(pipedOut, 8000);

Here, we are converting output stream to input stream. Therefore, we pass output stream to input stream in the input stream constructor. 

Now, we need to create a new single thread by ExecutorService.
                ExecutorService executorService = Executors.newSingleThreadExecutor();

As mentioned before, the PipedOutputStream task will be run in the new single thread. Thus, we need to implement Runnable interface which will write the data by TextWriter.write method to PipedOutputStream. The PipedOuputStream must be closed in the Runnable implementation. The reference of PipedOutputStream is already set in the PipedInputStream constructor; therefore, the data is transferred to the PipedInputStream during the writing operation.

public class PipedStreamRunable implements Runnable{
  ....
@Override 
         public void run() {
textWriter.write(outputStream);
....
}
   ....
}


The PipedStreamRunable will be passed to the executorService.execute method:
                 executorService.execute(new PipedStreamRunable(textWriterPiped, pipedOut));

Close the executorService:
                executorService.shutdown();

Now, we will print the data on the console by TextReader class. For this reason, we will pass the pipedIS to the TextReader class:
TextReader textReaderPiped = new TextReader(pipedIS);
textReaderPiped.print();



Comments

Popular posts from this blog

There is a process already using the admin port 4848 -- it probably is another instance of a GlassFish server; ERROR

How to install Homebrew in Mac OSX (High Sierra)

WildFly 19 and Log4J2