Java
Coding
OutputStream
InputStream
Data Conversion

How do I convert an OutputStream to an InputStream?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In Java, you do not truly convert a generic OutputStream into an InputStream. An OutputStream is a destination for bytes, while an InputStream is a source of bytes. What you actually do is either capture the written bytes so they can be read back later, or connect a writing stream to a reading stream with a pipe.

The Common Buffered Case

If the bytes are small enough to fit in memory, the normal pattern is:

  1. write into a ByteArrayOutputStream
  2. call toByteArray()
  3. wrap the result in a ByteArrayInputStream
java
1import java.io.ByteArrayInputStream;
2import java.io.ByteArrayOutputStream;
3import java.nio.charset.StandardCharsets;
4
5public class BufferExample {
6    public static void main(String[] args) throws Exception {
7        ByteArrayOutputStream out = new ByteArrayOutputStream();
8        out.write("hello stream".getBytes(StandardCharsets.UTF_8));
9
10        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
11        System.out.println(new String(in.readAllBytes(), StandardCharsets.UTF_8));
12    }
13}

This is the easiest answer when the data is already complete and comfortably memory-sized.

Why It Is Not a Generic Conversion

This works only because ByteArrayOutputStream stores bytes in memory and exposes them back as a byte array. A generic OutputStream does not necessarily keep anything readable afterward.

For example:

  • a FileOutputStream writes to a file
  • a socket output stream writes to the network
  • a servlet output stream writes to a client response

Those are destinations, not reusable in-memory buffers. So if you need an InputStream later, design for that upfront instead of hoping to reverse the stream type later.

The Streaming Case: Use Piped Streams

If you need one part of your program to write bytes while another part reads them immediately, use PipedOutputStream and PipedInputStream.

java
1import java.io.PipedInputStream;
2import java.io.PipedOutputStream;
3import java.nio.charset.StandardCharsets;
4
5public class PipeExample {
6    public static void main(String[] args) throws Exception {
7        PipedOutputStream out = new PipedOutputStream();
8        PipedInputStream in = new PipedInputStream(out);
9
10        Thread writer = new Thread(() -> {
11            try {
12                out.write("streamed data".getBytes(StandardCharsets.UTF_8));
13                out.close();
14            } catch (Exception e) {
15                throw new RuntimeException(e);
16            }
17        });
18
19        writer.start();
20        System.out.println(new String(in.readAllBytes(), StandardCharsets.UTF_8));
21        writer.join();
22    }
23}

This is not conversion either. It is a producer-consumer connection between two different stream types.

Sometimes the Real Answer Is a File

If the data is too large for memory and you do not want a pipe, writing to a temporary file and then opening a FileInputStream may be the most practical solution. That is slower than in-memory buffering, but it is often simpler than trying to manage large byte arrays.

So the design choice depends on the data size and timing:

  • small and complete now: byte array buffering
  • produced and consumed concurrently: piped streams
  • large and durable: temp file

Another useful rule is to separate API shape from storage shape. If an API requires an InputStream, it is often simpler to design your code around a readable source from the beginning instead of writing to an arbitrary sink first and then trying to reverse the flow.

Common Pitfalls

  • Assuming every OutputStream can somehow be turned into a readable stream after writing.
  • Using ByteArrayOutputStream for very large data and exhausting heap memory.
  • Using piped streams without considering threading and blocking behavior.
  • Forgetting to close or flush the writer before expecting the reader to see all data.
  • Solving a file-backed problem with a memory-only design when a temp file would be simpler.

Summary

  • You do not directly convert a generic OutputStream into an InputStream.
  • For in-memory data, use ByteArrayOutputStream plus ByteArrayInputStream.
  • For live producer-consumer flow, use PipedOutputStream and PipedInputStream.
  • For large data, a temporary file may be the better design.
  • The right answer depends on whether the bytes are buffered, streaming, or persistent.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.