Presents your JAVA E-NEWSLETTER for December 16, 2002 <-------------------------------------------> TRANSFER DATA WITH PIPED DATA STREAMS The Java I/O system is based upon the concept of streams of data. A similar concept is predominant in the UNIX operating system where the height of the concept is found in piping, which is the ability for one program to output data into another program's input. Java provides for this piping concept with the PipedInputStream and PipedOutputStream classes. Working together, they allow one Java component that pumps data out to an output stream to be connected to another component that reads the output in as an input stream. An example would be a component for logging information from an application and a component that shows a moving report of streaming data. By providing the logging component with a PipedOutputStream and the reporting component with the corresponding PipedInputStream, the two components can talk without having to know anything about each other. In its simplest form, the code would look like this: import java.io.*; public class Foo { static public void main(String[] args) throws IOException { PipedOutputStream pout = new PipedOutputStream(); PipedInputStream pin = new PipedInputStream(pout); for(int i=0; i < 100; i++) { pout.write( (byte)i ); } pout.close(); int j=0; while( (j = pin.read()) != -1) { System.err.println(j); } pin.close(); } } With this code, it's important to remember to call close() upon the output stream "pout", or else the second loop will never end. This coarse example is not the normal, or even desired, usage of piped streams. As the first loop's count gets larger, the buffer inside the PipedOutputStream will run out and cause problems, such as deadlocking the thread while it waits for something to remove data from the stream. This is why the Javadoc for piped streams states that PipedInputStream and PipedOutputStream must be used in multi-threaded environments. ----------------------------------------