I have searched the site and have found some answers, but i'm having trouble understanding the difference between these two classes. Can someone explain the differences between these two classes?
-
3`PrintStream` deals with `byte`s, while `PrintWriter` deals with `char`s. That's it. – Eng.Fouad Jul 07 '12 at 05:33
-
3but you can use PrintStream to write strings, chars, ints, etc. Perhaps i'm misunderstanding what you mean by it deals with bytes – i'mhungry Jul 07 '12 at 05:35
-
check http://way2java.com/io/printstream-vs-printwriter/ – Jigar Pandya Jul 07 '12 at 05:35
-
Possible duplicate: http://stackoverflow.com/questions/2822005/java-difference-between-printstream-and-printwriter – siaooo Dec 30 '12 at 05:24
-
4@Eng.Fouad: This question is a good one, it deserves a more detailed answer, specially if you think that System.out is actually a PrintStream, and ironically not a PrintWriter, while its goal is definitely to print characters, not bytes. See also: http://stackoverflow.com/questions/2822005/java-difference-between-printstream-and-printwriter which brings additional details. – mins May 24 '14 at 23:25
3 Answers
PrintStream
was the original bridge to deal with encoding characters and other datatypes. If you look at the javadoc for java.io.OutputStream
you'll see methods only for writing two distinct data types: byte
and int
.
In early versions of the JDK (1.0.x), when you wanted to write characters, you could do one of two things, write bytes to an output stream (which are assumed to be in the system default character set):
outputStream.write("foobar".getBytes());
or wrap another outputStream
in a PrintStream
:
PrintStream printStream = new PrintStream(outputStream);
printStream.write("foobar");
See the difference? PrintStream
is handling the character conversion to bytes, as well as encoding (the constructor call above uses the system default encoding, but you could pass it as a parameter). It also provides convenience methods for writing double
, boolean
, etc....
In fact System.out
and System.err
are defined as PrintStream
instances.
Along comes JDK 1.1, and they realize they need a better way to deal with pure character data, since PrintStream
still has the byte based methods for writing. So they introduced the Writer
abstract class to deal strictly with char
, String
and int
data.
PrintWriter
adds methods for other types like double
, boolean
, etc...
Nowadays PrintWriter
also has format()
/ printf()
methods for format printing, etc...
As a general rule, if you're writing character data, use Writer
instances. If you're writing binary (or mixed) data use OutputStream
instances.

- 3,065
- 8
- 32
- 47

- 11,523
- 2
- 23
- 33
-
1The history really helps, and explains why `System.out` and `System.err` are still `PrintStream`. – Franklin Yu Jan 11 '18 at 16:21
-
If PrintWriter is really a replacement for PrintStream, then why isn't PrintStream depricated? – DBear Apr 16 '22 at 19:14
From the Javadoc for PrintWriter:
Prints formatted representations of objects to a text-output stream. This class implements all of the print methods found in PrintStream. It does not contain methods for writing raw bytes, for which a program should use unencoded byte streams.
Think of it this way: a PrintStream
sits on top of some OutputStream
. Since output streams deal with bytes rather than characters, the PrintStream must take responsibility for encoding characters into bytes. The OutputStream 'merely' writes the bytes out to a file/console/socket whatever.
A PrintWriter
, on the other hand, sits on top of a Writer
. Since the Writer is responsible for encoding characters into bytes, the PrintWriter does not do encoding. I just knows about newlines etc. (Yes, PrintWriters do have constructors that take File
s and OutputStream
s, but those are simply conveniences. For example, PrintWriter(OutputStream)
.
Creates a new PrintWriter, without automatic line flushing, from an existing OutputStream. This convenience constructor creates the necessary intermediate OutputStreamWriter, which will convert characters into bytes using the default character encoding.
BTW, In case you are thinking that the PrintWriter
really doesn't have much utility, remember that both PrintWriter and PrintStream absorb IOException
s from printing logic.

- 13,254
- 3
- 41
- 52
To add Matt's answer:
I compared PrintStream
and PrintWriter
,
the most useful part, the constructor ClassName
(String fileName, String charsetName)
and the print(), println(), printf()/format() functions are supported by both classes.
The differences are:
Since JDK1.0
vs JDK1.1
Constructors:
PrintStream(OutputStream out, boolean autoFlush, String charsetName)
PrintWriter(Writer wr)
PrintWriter(Writer wr, boolean autoFlush)
Methods inherited from FilterOutputStream
/OutputStream
vs Writer
, the difference boils down to byte
vs char
:
PrintStream.write(byte[] buffer, int offset, int count)
PrintStream.write(byte[] buffer)
PrintStream.write(int oneByte)
PrintWriter.write(int oneChar)
PrintWriter.write(char[] buf)
PrintWriter.write(char[] buf, int offset, int count)
PrintWriter.write(String str)
PrintWriter.write(String str, int offset, int count)
PrintStream.printf()
corresponds to PrintWriter.format()
It indeed looks like in 1.1. they thought out a better class, but could not remove the old 1.0 class without breaking existing programs.

- 16,368
- 4
- 94
- 127