|
|
Input and Output Streams |
Thejava.iopackage contains two classes,PipedInputStreamand
PipedOutputStream, that implement the input and output components of a pipe. Pipes are used to channel the output from one program (or thread) into the input of another.
Piped input and output streams are convenient for methods that produce output to be used as input by someone else. For example, suppose that you are writing a class that implements various text utilities such as sorting and reversing text. It would be nice if the output of one of these methods could be used as the input for another so you could string a series of these methods together to perform some function. The pipe shown here uses reverse, sort, and reverse on a list of words to create a list of rhyming words:
Without piped streams, you would have to create a temporary file between each step:
Let's look at a program that implements the reverse and sort methods described above using piped streams, and then uses the reverse and sort methods in the pipe shown above to generate a list of rhyming words.First, the RhymingWords class contains three methods:
main,reverse, andsort. Themainmethod provides the code for the main program, which opens an input file, uses the other two methods to reverse, sort, and reverse the words in the input file, and then writes the results to the standard output stream.
reverseandsortare designed to be used in a pipe. Bothreverseandsortread data from anInputStream, process it (either reversing the strings or sorting them), and produce aPipedInputStreamsuitable for another method to read. Let's look in detail atreverse; thesortmethod is very similar toreverseand doesn't warrant its own discussion.Thepublic static InputStream reverse(InputStream source) { PipedOutputStream pos = null; PipedInputStream pis = null; try { DataInputStream dis = new DataInputStream(source); pos = new PipedOutputStream(); pis = new PipedInputStream(pos); PrintStream ps = new PrintStream(pos); new WriteReversedThread(ps, dis).start(); } catch (Exception e) { System.out.println("RhymingWords reverse: " + e); } return pis; }reversemethod takes anInputStreamcalledsourcethat contains a list of strings to be reversed.reversemaps aDataInputStreamonto thesourceInputStreamso that it can use theDataInputStream'sreadLinemethod to read each line from the file.DataInputStreamis a filtered stream which must be attached to (mapped onto) anInputStreamwhose data is to be filtered when read. Working with Filtered Streams talks about this.Next
reversecreates aPipedOutputStreamand connects aPipedInputStreamto it. Remember that aPipedOutputStreammust be connected to aPipedInputStream. Thenreversemaps aPrintStreamonto thePipedOutputStreamso that it can use thePrintStream'sprintlnmethod to write strings to thePipedOutputStream.Now
reversecreates a WriteReversedThread thread object, hands it to two streams--thePrintStreamattached to thePipedOutputStreamand theDataInputStreamattached tosource--and starts it. TheWriteReversedThreadobject read words from theDataInputStream, reverses them, and writes the output to thePrintStream(thereby writing the output to a pipe). TheThreadobject allows each end of the pipe to run independently of one another and prevents themainmethod from locking up if one end of a pipe blocks waiting for an I/O call to complete.Here's the
runmethod forWriteReversedThread:public void run() { if (ps != null && dis != null) { try { String input; while ((input = dis.readLine()) != null) { ps.println(reverseIt(input)); ps.flush(); } ps.close(); } catch (IOException e) { System.out.println("WriteReversedThread run: " + e); } } }Because the
PipedOutputStreamis connected to thePipedInputStream, all data written to thePipedOutputStreamflows into thePipedInputStream. The data can be read from thePipedInputStreamby another program or thread.reversereturns thePipedInputStreamfor use by the calling program.The
sortmethod follows the same pattern:Calls to
- Open piped output stream.
- Connect piped input stream to it.
- Using a SortThread object, read from the piped input stream and write to the piped output stream, which is the piped input stream for someone else.
- Hand the now-full piped input stream to someone else to read.
reverseandsortcan be cascaded together so that the output from one method can be the input for the next method. In fact, themainmethod does just that. It cascades calls toreverse,sort, and thenreverseto generate a list of rhyming words:When you runInputStream rhymedWords = reverse(sort(reverse(words)));RhymingWordson this file of words you will see this output:If you look closely you can see that rhyming words such as environment, development, argument, and component are grouped together.Java interface image language communicate integrate native string network stream program application animation exception primer container user graphics threads tools class bolts nuts object applet environment development argument component input output anatomy securitySee Also
![]()
java.io.PipedInputStream
![]()
java.io.PipedOutputStream
|
|
Input and Output Streams |