Streams provide the most direct access to the binary content, so any InputStream
/ OutputStream
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
which adds the "ability to print representations of various data values conveniently". This allows to use System.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
/ DataInputStream
.
With the Writer
and Reader
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);
}