In Java 1.1 and later, streams are primarily intended for data that can be read as pure bytes—basically byte data and numeric data encoded as binary numbers of one sort or another. Streams are specifically not intended for use when reading and writing text, including both ASCII text, like “Hello World,” and numbers formatted as text, like “3.1415929.” For these purposes, you should use readers and writers.
Input and output streams are fundamentally byte-based. Readers and writers are based on
characters, which can have varying widths depending on the character
set. For example, ASCII and ISO Latin-1 use one-byte characters.
Unicode uses two-byte characters. UTF-8 uses characters of varying
width (between one and three bytes). Since characters are ultimately
composed of bytes, readers take their input from streams. However,
they convert those bytes into char
s according to a
specified encoding format before passing them along. Similarly,
writers convert char
s to bytes according to a
specified encoding before writing them onto some underlying stream.
The
java.io.Reader
and
java.io.Writer
classes are abstract superclasses for
classes that read and write character-based data. The subclasses are
notable for handling the conversion between different character sets.
There are nine reader and eight
writer
classes in the core Java API, all in the java.io
package:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For the most part, these classes have methods that are extremely
similar to the equivalent stream classes. Often the only difference
is that a byte
in the signature of a stream method
is replaced by a char
in the signature of the
matching reader or writer method. For example, the
java.io.OutputStream
class declares these three
write()
methods:
public abstract void write(int i) throws IOException public void write(byte[] data) throws IOException public void write(byte[] data, int offset, int length) throws IOException
The java.io.Writer
class, therefore, declares
these three write()
methods:
public void write(int i) throws IOException public void write(char[] data) throws IOException public abstract void write(char[] data, int offset, int length) throws IOException
As you can see, the six signatures are identical except that in the
latter two methods the byte
array
data
has changed to a char
array. There’s also a less obvious difference not reflected in
the signature. While the int
passed to the
OutputStream
write()
method is
reduced modulo 256 before being output, the int
passed to the Writer
write()
method is reduced modulo 65,536. This reflects the different ranges
of char
s and byte
s.
java.io.Writer
also has two more
write()
methods that take their data from a
string:
public void write(String s) throws IOException public void write(String s, int offset, int length) throws IOException
Because streams don’t know how to deal with character-based
data, there are no corresponding methods in the
java.io.OutputStream
class.
3.131.152.166