Java Writer
Jakob Jenkov |
The Java Writer class (java.io.Writer
) is the base class for all Writer
subclasses in the Java IO API.
A Writer
is like an OutputStream
except that it is character based rather
than byte based. In other words, a Writer
is intended for writing text, whereas an
OutputStream
is intended for writing raw bytes.
Characters in Unicode
Today, many applications use Unicode (typically UTF-8 or UTF-16) to store text data. It may take one or more bytes to represent a single character in UTF-8. In UTF-16 each character takes 2 bytes to represent. To write UTF-8 or UTF-16 correctly you need to know which of the two formats you want to store the text in, and you need to know how to properly encode characters using the chosen format.
This is where the Java Writer
class comes in handy. The Java Writer
subclasses can
normally handle UTF-8 and UTF-16 encoding for you, so you don't have to worry about that.
Writer Subclasses
You will normally use a Writer
subclass rather than a Writer
directly.
Subclasses of Writer
include OutputStreamWriter
, CharArrayWriter
,
FileWriter
, plus many others. Here is a list of the Java Writer
subclasses:
- FileWriter
- OutputStreamWriter
- BufferedWriter
- PipedWriter
- CharArrayWriter
- FilterWriter
- StringWriter
- PrintWriter
Writers and Destinations
A Java Writer
is typically connected to some destination of data like a file, char array, network socket
etc. This is also explained in more detail in the Java IO Overview text.
write(int)
The Java Writer
write(int)
method writes the lower 16 bit of the int
to the destination the Writer
is connected to, as a single character. Here is an example of writing
a single character to a Java Writer
:
Writer writer = new FileWriter("data/output.txt"); writer.write('A');
write(char[])
The Java Writer
also has a write(char[])
method which can write an array of characters
to the destination the Writer
is connected to. The write(char[])
method returns
the number of characters actually written to the Writer
. Here is an example of writing an array of
chars to a Java Writer
:
Writer writer = new FileWriter("data/output.txt"); char[] chars = new char[]{'A','B','C','D','E'}; writer.write(chars);
Write Performance
It is faster to write an array of characters to a Java Writer than writing one character at a time. The speedup
can be quite significant - up to 10 x higher or more. Therefore it is recommended to use the write(char[])
methods whenever possible.
The exact speedup you get depends on the underlying OS and hardware of the computer you run the Java code on.
The speedup depends on issues like memory speed, hard disk speed and buffer sizes, or network card speed and buffer
sizes, depending on which destination the Writer
sends its data to.
Transparent Buffering via BufferedWriter
You can get transparent buffering of bytes written to a Java Writer
by wrapping it in a
Java BufferedWriter . All bytes written to the BufferedWriter
will first get buffered inside an internal byte array in the BufferedWriter
. When the buffer is
full, the buffer is flushed to the underlying Writer
all at once. Here is an example of wrapping a
Java Writer
in a BufferedWriter
:
int bufferSize = 8 * 1024; Writer writer = new BufferedWriter( new FileWriter("c:\\data\\output-file.txt"), bufferSize );
You can read more about the BufferedWriter
in my BufferedWriter tutorial.
flush()
The Java Writer
's flush()
method flushes all data written to the Writer
to the underlying data destination. For instance, if the Writer
is a FileWriter
then bytes written to the FileWriter
may not have been fully written to disk yet. The data might
be buffered in OS memory somewhere, even if your Java code has written it to the FileWriter
.
By calling flush()
you can assure that any buffered data will be flushed (written) to disk (or network, or whatever
else the destination of your Writer
has). Here is an example of flushing data written to
a Java Writer
by calling its flush()
method:
writer.flush();
Close a Writer
Once you are done writing characters to a Java Writer
you should close it. You close an
Writer
by calling its close()
method.
Here is an example of closing a Java Writer
:
Writer writer = new FileWriter("c:\\data\\output-text.txt"); while(hasMoreCharacters()) { int character = getNextCharacter(); writer.write(character); } writer.close();
The concrete implementations of hasMoreCharacters()
and getNextCharacter()
are left out, but
they are not really super important to understand the principle of this example. What matters is, that
once the while
loop ends, and you are done writing data to the Writer
,
its close()
method is called, which closes the Writer
.
The above example is not fully robust though. In case the write()
method throws an exception,
the close()
method will never get called. The exception will make the program exit whatever
method the above code is located in.
Instead, you should use the
Java try with resources construct to close
the Writer
. Here is an example that closes a Java Writer
using
the try-with-resources construct:
try( Writer writer = new FileWriter("c:\\data\\output-text.txt")) { while(hasMoreCharacters()) { int character = getNextCharacter(); writer.write(character); } }
Once the try
block is exited, the close()
method of the Writer
is called automatically, because the Writer
was declared inside the parentheses of the
try
block. Even if an exception is thrown from inside the try
block, the
close()
method is still called before the exception is propagated up the call stack.
Tweet | |
Jakob Jenkov |