The java.io.PipedInputStream class and java.io.PipedOutputStream class provide a convenient means to move streaming data from one thread to another. Output from one thread becomes input for the other thread.
Piped streams are normally created in pairs. The piped output stream becomes the underlying source for the piped input stream.
To use the piped output stream as the underlaying source for the piped input stream, you might write something like this:
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
Simple Example
This simple example is a little deceptive because these lines of code will normally be in different methods, and perhaps even different classes.
Some mechanism must be established to pass a reference to the PipedOutputStream into the thread that handles the PipedInputStream.
Or you can create them in the same thread; then pass a reference to the connected stream into a separate thread. Alternatively, you can reverse this:
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
Or you can create them both unconnected, then use one or the other's connect() method to link them:
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos);
Otherwise, these classes just have the usual
read(),
write(),
flush(),
close(), and
available()
methods like all stream classes.
Example of a Java program using PipedOutputStream to send data to PipedInputStream
Here is a Java program demonstrating how to use `PipedOutputStream` and `PipedInputStream` to send data from one stream to the other. The program uses two threads: one to write data to the `PipedOutputStream` and another to read it from the `PipedInputStream`.
import java.io.*;
public class PipedStreamExample {
public static void main(String[] args) {
// Create piped streams
try (PipedOutputStream pipedOutputStream = new PipedOutputStream();
PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream)) {
// Writer thread: writes data into the PipedOutputStream
Thread writerThread = new Thread(() -> {
try {
for (int i = 1; i <= 5; i++) {
String message = "Message " + i;
pipedOutputStream.write(message.getBytes());
System.out.println("Writer: Sent - " + message);
Thread.sleep(500); // Simulate some delay
}
} catch (IOException | InterruptedException e) {
System.err.println("Writer thread error: " + e.getMessage());
}
});
// Reader thread: reads data from the PipedInputStream
Thread readerThread = new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(pipedInputStream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Reader: Received - " + line);
}
} catch (IOException e) {
System.err.println("Reader thread error: " + e.getMessage());
}
});
// Start threads
writerThread.start();
readerThread.start();
// Wait for threads to finish
writerThread.join();
readerThread.join();
} catch (IOException | InterruptedException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Explanation of the Program
PipedOutputStream and PipedInputStream
These are connected streams; whatever is written into the PipedOutputStream can be read from the PipedInputStream.
Threaded Model
A writer thread writes data to the PipedOutputStream.
A reader thread reads the same data from the PipedInputStream.
BufferedReader
Used to read the data efficiently from the PipedInputStream.
Synchronization
The join method ensures the main thread waits for both the writer and reader threads to finish.
Error Handling
Handles IOException and InterruptedException gracefully.
Simulated Delay
The Thread.sleep(500) introduces a delay to mimic real-world scenarios of data processing.
This example demonstrates a practical use of `PipedOutputStream` and `PipedInputStream` in a multithreaded environment.
The program starts by creating a PipedOutputStream and a PipedInputStream, connecting them together. Then it creates two threads, one that writes "Hello, World!" to the PipedOutputStream, and another that reads data from the PipedInputStream and prints it to the console. The program starts both threads, which run concurrently and share the data between them via the pipe.