Advanced Java Services | PipedOutputStream und PipedInputStream |
Aus der API
A piped output stream can be connected to a piped input stream to create a communications pipe. The piped output stream is the sending end of the pipe. Typically, data is written to a PipedOutputStream object by one thread and data is read from the connected PipedInputStream by some other thread. Attempting to use both objects from a single thread is not recommended as it may deadlock the thread. The pipe is said to be broken if a thread that was reading data bytes from the connected piped input stream is no longer alive.
Aus der API
A piped input stream should be connected to a piped output stream; the piped input stream then provides whatever data bytes are written to the piped output stream. Typically, data is read from a PipedInputStream object by one thread and data is written to the corresponding PipedOutputStream by some other thread. Attempting to use both objects from a single thread is not recommended, as it may deadlock the thread. The piped input stream contains a buffer, decoupling read operations from write operations, within limits. A pipe is said to be broken if a thread that was providing data bytes to the connected piped output stream is no longer alive.
Die Graphik zeigt das Zusammenwirken von PipedOutputStream und PipedInputStream, die in verschiedenen Threads laufen sollen.
Sinnvollerweise ist ein PipedOutputStream immer mit einem PipedInputStream verbunden (und umgekehrt). Die Verbindung wird dabei über die Konstruktoren hergestellt.
Hier schreibt ein PipedOutputStream einige Daten in eine Pipe die dann von einem PipedInputStream ausgelesen werden.
Der schreibende Thread wird mit einem DataOutputStream realisiert, der auf einen PipedOutputStream aufsetzt.
class WriteToPipe extends Thread { PipedOutputStream pos; public WriteToPipe(PipedOutputStream pos) { this.pos = pos; } public void run() { try { DataOutputStream out = new DataOutputStream(pos); for(int i = 1; i < 8; i++) { out.writeInt(i); System.out.println("write value = " + i); } out.close(); System.out.println("end of writing"); } catch(IOException e) { e.printStackTrace(); } } }
Der lesend Thread wird analog mit einem DataInputStream realisiert, der auf einen PipedInputStream aufsetzt..
class ReadFromPipe extends Thread { PipedInputStream pis; public ReadFromPipe(PipedInputStream pis) { this.pis = pis; } public void run() { DataInputStream in = new DataInputStream(pis); for(;;) { try { int iValue = in.readInt(); System.out.println("read value = " + iValue); } catch(IOException ex) { //System.out.println(ex); // EOFException break; } } System.out.println("end of reading"); } }
Main
Welchen Stream man zuerst anlegt ist egal. Wichtig ist nur, daß ein Stream den anderen kennt.
sleep() wurde lediglich deshalb eingebaut, damit man sieht, daß nach dem Ende des Schreibens die Pipe noch weiter besteht.
public static void main(String[] args) throws IOException, InterruptedException { //PipedOutputStream pos = new PipedOutputStream(); //PipedInputStream pis = new PipedInputStream(pos); // geht genauso PipedInputStream pis = new PipedInputStream(); PipedOutputStream pos = new PipedOutputStream(pis); // throws IOException Thread outThread = new WriteToPipe(pos); outThread.start(); Thread.sleep(3000); Thread inThread = new ReadFromPipe(pis); inThread.start(); }
Output
write value = 1 write value = 2 write value = 3 write value = 4 write value = 5 write value = 6 write value = 7 end of writing read value = 1 read value = 2 read value = 3 read value = 4 read value = 5 read value = 6 read value = 7 end of reading