Java I/O: Binary versus
Character and Chaining Streams
versus Character Streams
we are working with binary data such as images and sounds, we need to use
binary mode files. For other purposes, we would use character streams, as in
the reader and writer classes described earlier. These reader/writer classes
offer us the following benefits:
handle any character in the Unicode
character set; the byte streams are limited to ISO Latin-1 eight-bit bytes.
that use character streams can easily be internationalized because they do not depend
on a specific character encoding.
character stream classes use internal buffering, inherently they are more
efficient than byte streams.
general, use the FileInputStream and
FileOutputStream classes to read and
write binary data from and to image files, sound files, video files, configuration
files, and so on. These classes can also be used to read/write ASCII-based text files. To read/write
modern Unicode-based text files, use the FileReader
and FileWriter classes.
examine this line of code carefully
BufferedReader reader = new
we saw how a BufferedReader instance
is opened on top of a FileReader
object. This is called wrapping or chaining streams. Very
rarely, a program uses a single stream object. Generally, several stream
objects (in a series) are chained to process the data more efficiently. The
Java I/O libraries provide several such wrappings. The wrappings help in
processing and managing the data more efficiently by providing the additional
convenience methods in the subclasses. Connecting several stream classes together
helps in getting the data in the required format. Each class performs a
specific task on the data and forwards it to the next class in the chain. A
typical example of this could be a data-backup utility. Such a program would
chain several streams to compress, encrypt, transmit, receive, and finally
store the data in a remote file. Adjoining figure shows one such wrapping for
an input stream
Here, we first open the
FileInputStream on a physical data source.
The output of this is
buffered in the BufferedInputStream object.
We wrap this with a
DataInputStream for convenient handling of primitive data types.
· The DataInputStream class
provides several read methods, such as readByte, readChar, readDouble, and so
on, that operate on primitive data types.
similar wrapping is provided for writer classes as shown in the following
· In this case, the program
writes data to a DataOutputStream by using its write methods that accept
primitive data types.
The data written is buffered
in a BufferedOutputStream object for efficient disk writing.
Finally, the data is written
out to a physical device using the FileOutputStream object