Streams provide the most direct access to the binary content, so any [InputStream](<https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html>)
/ [OutputStream](<https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html>)
implementations always operate on int
s and byte
s.
// Read a single byte from the stream
int b = inputStream.read();
if (b >= 0) { // A negative value represents the end of the stream, normal values are in the range 0 - 255
// Write the byte to another stream
outputStream.write(b);
}
// Read a chunk
byte[] data = new byte[1024];
int nBytesRead = inputStream.read(data);
if (nBytesRead >= 0) { // A negative value represents end of stream
// Write the chunk to another stream
outputStream.write(data, 0, nBytesRead);
}
There are some exceptions, probably most notably the [PrintStream](<https://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html>)
which adds the “ability to print representations of various data values conveniently”. This allows to use [System.out](<https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#out>)
both as a binary InputStream
and as a textual output using methods such as System.out.println()
.
Also, some stream implementations work as an interface to higher-level contents such as Java objects (see Serialization) or native types, e.g. [DataOutputStream](<https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html>)
/ [DataInputStream](<https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html>)
.
With the [Writer](<https://docs.oracle.com/javase/7/docs/api/java/io/Writer.html>)
and [Reader](<https://docs.oracle.com/javase/7/docs/api/java/io/Reader.html>)
classes, Java also provides an API for explicit character streams. Although most applications will base these implementations on streams, the character stream API does not expose any methods for binary content.
// This example uses the platform's default charset, see below
// for a better implementation.
Writer writer = new OutputStreamWriter(System.out);
writer.write("Hello world!");
Reader reader = new InputStreamReader(System.in);
char singleCharacter = reader.read();
Whenever it is necessary to encode characters into binary data (e.g. when using the InputStreamWriter
/ OutputStreamWriter
classes), you should specify a charset if you do not want to depend on the platform’s default charset. When in doubt, use a Unicode-compatible encoding, e.g. UTF-8 which is supported on all Java platforms. Therefore, you should probably stay away from classes like FileWriter
and FileReader
as those always use the default platform charset. A better way to access files using character streams is this:
Charset myCharset = StandardCharsets.UTF_8;
Writer writer = new OutputStreamWriter( new FileOutputStream("test.txt"), myCharset );
writer.write('Ä');
writer.flush();
writer.close();
Reader reader = new InputStreamReader( new FileInputStream("test.txt"), myCharset );
char someUnicodeCharacter = reader.read();
reader.close();
One of the most commonly used Reader
s is BufferedReader
which provides a method to read whole lines of text from another reader and is presumably the simplest way to read a character stream line by line:
// Read from baseReader, one line at a time
BufferedReader reader = new BufferedReader( baseReader );
String line;
while((line = reader.readLine()) != null) {
// Remember: System.out is a stream, not a writer!
System.out.println(line);
}