Duplicating a Stream as It Is Written
Problem
You want anything written to a
stream, such as the standard output
System.out
or the standard error
System.err
, to appear there but
also be logged into a file.
Solution
Subclass PrintStream
and have its write( )
methods write to two streams. Then use
system.setErr( )
or setOut( )
as in Section 9.7 to replace the existing standard
stream with this “tee” PrintStream
subclass.
Discussion
Classes are meant to be subclassed. Here we’re just subclassing
PrintStream
and adding a bit of
functionality: a second PrintStream
! I wrote a
class called TeePrintStream
, named after the
ancient
Unix command tee.
That command allowed you to duplicate, or “tee off,” a
copy of the data being written on a
"pipeline” between two
programs.
The original Unix tee command is used like this:
the
|
character creates
a pipeline in which the standard output of one program becomes the
standard input to the next. This often-used example of pipes shows
how many users are logged into a Unix server:
who | wc -l
This runs the who program (which lists who is
logged into the system, one name per line along with the terminal
port and login time) with its output, instead of going to the
terminal, going into the standard input of the word count
(wc) program. Here wc is
being asked to count lines, not words; hence the
-l
option. To tee a copy of
the intermediate data into a file, you might say:
who | tee wholist | wc -l
which creates a file wholist
containing the data. For the curious, ...
Get Java Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.