new BufferedOutputStream(new FileOutputStream(path));
You create a FileOutputStream with the path, put a BufferedOutputStream in front of it, and use
the buffered stream object. This scheme enables you to buffer output destined for the file.
You must retain a reference to the FileOutputStream object if you want to invoke methods on it later
because there is no way to obtain the downstream object from a Filter stream. However, you should rarely
need to work with the downstream object. If you do keep a reference to a downstream object, you must ensure
that the first upstream object is flushed before operating on the downstream object because data written to
upper streams may not have yet been written all the way downstream. Closing an upstream object also closes
all downstream objects, so a retained reference may cease to be usable.
The Buffered character streams also understand lines of text. The newLine method of
BufferedWriter writes a line separator to the stream. Each system defines what constitutes a line
separator in the system String property line.separator, which need not be a single character. You
should use newLine to end lines in text files that may be read by humans on the local system (see "System
Properties" on page 663).
The method readLine in BufferedReader returns a line of text as a String. The method readLine
accepts any of the standard set of line separators: line feed (\n), carriage return (\r), or carriage return
followed by line feed (\r\n). This implies that you should never set line.separator to use any other
sequence. Otherwise, lines terminated by newLine would not be recognized by readLine. The string
returned by readLine does not include the line separator. If the end of stream is encountered before a line
separator, then the text read to that point is returned. If only the end of stream is encountered readLine
returns null.
20.5.4. Piped Streams
Piped streamsPipedInputStream, PipedOutputStream, PipedReader, and PipedWriterare
used as input/output pairs; data written on the output stream of a pair is the data read on the input stream. The
pipe maintains an internal buffer with an implementation-defined capacity that allows writing and reading to
proceed at different ratesthere is no way to control the size of the buffer.
Pipes provide an I/O-based mechanism for communicating data between different threads. The only safe way
to use Piped streams is with two threads: one for reading and one for writing. Writing on one end of the pipe
blocks the thread when the pipe fills up. If the writer and reader are the same thread, that thread will block
permanently. Reading from a pipe blocks the thread if no input is available.
To avoid blocking a thread forever when its counterpart at the other end of the pipe terminates, each pipe
keeps track of the identity of the most recent reader and writer threads. The pipe checks to see that the thread
at the other end is alive before blocking the current thread. If the thread at the other end has terminated, the
current thread will get an IOException.
The following example uses a pipe stream to connect a TextGenerator tHRead with a thread that wants to
read the generated text. First, the text generator:
class TextGenerator extends Thread {
private Writer out;
public TextGenerator(Writer out) {
this.out = out;
}