Input and Output Streams |
Thejava.io
package contains two classes,PipedInputStream
andPipedOutputStream
, 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
. Themain
method 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.
reverse
andsort
are designed to be used in a pipe. Bothreverse
andsort
read data from anInputStream
, process it (either reversing the strings or sorting them), and produce aPipedInputStream
suitable for another method to read. Let's look in detail atreverse
; thesort
method is very similar toreverse
and 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; }reverse
method takes anInputStream
calledsource
that contains a list of strings to be reversed.reverse
maps aDataInputStream
onto thesource
InputStream
so that it can use theDataInputStream
'sreadLine
method to read each line from the file.DataInputStream
is a filtered stream which must be attached to (mapped onto) anInputStream
whose data is to be filtered when read. Working with Filtered Streams talks about this.Next
reverse
creates aPipedOutputStream
and connects aPipedInputStream
to it. Remember that aPipedOutputStream
must be connected to aPipedInputStream
. Thenreverse
maps aPrintStream
onto thePipedOutputStream
so that it can use thePrintStream
'sprintln
method to write strings to thePipedOutputStream
.Now
reverse
creates a WriteReversedThread thread object, hands it to two streams--thePrintStream
attached to thePipedOutputStream
and theDataInputStream
attached tosource
--and starts it. TheWriteReversedThread
object read words from theDataInputStream
, reverses them, and writes the output to thePrintStream
(thereby writing the output to a pipe). TheThread
object allows each end of the pipe to run independently of one another and prevents themain
method from locking up if one end of a pipe blocks waiting for an I/O call to complete.Here's the
run
method 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
PipedOutputStream
is connected to thePipedInputStream
, all data written to thePipedOutputStream
flows into thePipedInputStream
. The data can be read from thePipedInputStream
by another program or thread.reverse
returns thePipedInputStream
for use by the calling program.The
sort
method 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.
reverse
andsort
can be cascaded together so that the output from one method can be the input for the next method. In fact, themain
method does just that. It cascades calls toreverse
,sort
, and thenreverse
to generate a list of rhyming words:When you runInputStream rhymedWords = reverse(sort(reverse(words)));RhymingWords
on 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 |