What is the difference bertween the following three file writing declarations:
PrintWriter out = new PrintWriter(new FileOutputStream(....));
vs.
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(....));
vs.
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(....)));
Is one method deprecated?
Are all methods suitable for text files?
Lars
Ryan Stewart - 29 Jan 2005 03:24 GMT
> What is the difference bertween the following three file writing declarations:
> PrintWriter out = new PrintWriter(new FileOutputStream(....));
[quoted text clipped - 7 lines]
>
> Are all methods suitable for text files?
None are deprecated. The main difference is what methods are available to you
via the out variable. Since they are all Writers, they all work with character
data.
See http://java.sun.com/docs/books/tutorial/essential/io/index.html
Adam Maass - 29 Jan 2005 06:43 GMT
> What is the difference bertween the following three file writing
> declarations:
[quoted text clipped - 11 lines]
>
> Lars
First: There is a Grand Division between the classes in java.io between
Writers/Readers and InputStreams/OutputStreams.
The Writer/Reader classes are character-oriented. The
InputStream/OutputStream classes are byte oriented.
These are not the same thing; a Java char is a 16-bit Unicode value. A byte
is an 8-bit value.
Representing characters in bytes can be done via an "encoding." An encoding
is a set of rules for translating between the 16-bit Unicode characters and
8-bit bytes. And also for translating from a sequence of 8-bit bytes to
16-bit Unicode. Your platform has a default encoding, probably some superset
of ASCII.
A PrintWriter is a character-oriented output class that has a whole bunch of
methods on it for conveniently translating various types to character
representations, and then pushing those characters onto another Writer. It
takes in its constructor another Writer, or as you have noted, an
OutputStream. If it takes an OutputStream, it does not use it directly, but
wraps it in an OutputStreamWriter internally, using your platform's default
encoding.
OutputStreamWriter is a character-oriented output class with limited scope;
it can output a single character or a single String at a time. It takes an
OutputStream in its constructor. It writes the characters it takes onto the
OutputStream. Its purpose in life is to use an encoding to translate between
the 16-bit char values it gets and the appropriate (by the encoding) bytes
that represent those char values.
BufferedWriter is a character-oriented output class with limited scope; it
can output a single character or a single String at a time. It takes another
Writer in its constructor. Its role in life is to batch together multiple
characters and make calls on its wrapped Writer with those batched
characters.
All of the calls above will enable you to write characters to a file, using
your platform's default encoding. The first version gets you some useful
methods for translating say, an int, into characters before being pushed out
to the file. The second version omits this but still allows a single
character at a time to be written -- each time you do this, however, there
is direct access to the underlying file and is probably rather inefficient.
The third version is very much like the second except that characters are
pushed out to the file in batches, even if you only write one character at a
time.
What you're probably looking for is something like this:
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
new BufferedOutputStream(
new FileOutputStream(...))));
This version gets you all of the nice "translate types to characters"
methods of the PrintWriter. It explicitly converts from characters to bytes
with an OutputStreamWriter. It uses a BufferedOutputStream (like the
BufferedWriter, but on bytes instead of characters) to batch writes.
Finally, the whole thing goes to a file via a FileOutputStream.
By the Way, using a buffer is generally a good thing when doing input or
output. And I can't really think of a good reason why you would buffer
characters when you can buffer bytes instead.
-- Adam Maass
Ryan Stewart - 29 Jan 2005 13:58 GMT
[...]
> PrintWriter pw = new PrintWriter(
> new OutputStreamWriter(
> new BufferedOutputStream(
> new FileOutputStream(...))));
[...]
The OutputStreamWriter is unnecessary as PrintWriter has a constructor that
takes an OutputStream.
Aleksander =?iso-8859-2?Q?Str=B1czek?= - 30 Jan 2005 00:59 GMT
> What is the difference bertween the following three file writing declarations:
> PrintWriter out = new PrintWriter(new FileOutputStream(....));
[quoted text clipped - 4 lines]
>
> Is one method deprecated?
AFAIK none of those method are deprecated.
> Are all methods suitable for text files?
Not exactly.
If you want to write text file in non-default charset, you have to use
OutputStreamWriter, in wich you can specify charset in constructor.
> PrintWriter out = new PrintWriter(new FileOutputStream(....));
With this you can use print(...) methods, cannot specify charset,
buffering not exists (slow).
> OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(....));
With this you can specify charset, cannot use print(...) methods,
buffering not exists (slow).
> BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(....)));
With this you can specify charset, cannot use print(...) methods,
buffering exists (fast).
So if you want:
use print(...) methods
specify charset
fast writing (buffering)
you should use:
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(....))));
If you want to write text in default charset you can omit OutputStreamWriter:
PrintWriter out = new PrintWriter(
new BufferedWriter(new FileOutputStream(....)));

Signature
HTH, Olek
John C. Bollinger - 31 Jan 2005 15:09 GMT
> What is the difference bertween the following three file writing declarations:
> PrintWriter out = new PrintWriter(new FileOutputStream(....));
[quoted text clipped - 6 lines]
>
> Are all methods suitable for text files?
PrintWriter is a convenience Writer that offers methods to handle
conversion of Java data types to text automagically, as well as
convenience methods to output the appropriate system-defendant line
separator string. The characters go to an underlying Writer, which
determines their disposition. When you construct a PrintWriter around
an OutputStream (instead of around a Writer) the PrintWriter constructor
creates an intermediary OutputStreamWriter.
OutputStreamWriter is a Writer that wraps an OutputStream so as to
appropriately convert characters written to it into bytes written to the
underlying stream. It is the bridge between Writers and OutputStreams.
It does not offer the convenience formatting methods that PrintWriter
does.
BufferedWriter is a Writer that wraps an underlying Writer and buffers
the data written to it, which is often useful for improving I/O
performance. It does not offer the convenience formatting methods that
PrintWriter does.
None of these classes is deprecated, but the resulting Writers (and
Writer chains) have differing behavior because they have different
classes. Refer to my synopses above for more information, or better
yet, read the classes' API docs. In one sense, all of the above are
suitable for text files. In another sense, none of them are suitable
because none of them specify the charset to use when converting
characters to bytes. (The charset name would be a second argument to
the relevant OutputStreamWriter constructor.)
John Bollinger
jobollin@indiana.edu