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.
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.
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 Files and OutputStreams, 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 IOExceptions from printing logic.
Difference between Printstream outputting bytes and Printwriter outputting characters in Java
PrintWriter System.out differences...?
PrintStream v/s PrintWriter - Oracle Forums
what difference between PrintWriter and PrintStream?
This might sound flippant, but PrintStream prints to an OutputStream, and PrintWriter prints to a Writer. Ok, I doubt I'll get any points for stating the obvious. But there's more.
So, what is the difference between an OutputStream and a Writer?
Both are streams, with the primary difference being a OutputStream is a stream of bytes while a Writer is a stream of characters.
If an OutputStream deals with bytes, what about PrintStream.print(String)? It converts chars to bytes using the default platform encoding. Using the default encoding is generally a bad thing since it can lead to bugs when moving from one platform to another, especially if you are generating the file on one platform and consuming it on another.
With a Writer, you typically specify the encoding to use, avoiding any platform dependencies.
Why bother having a PrintStream in the JDK, since the primary intent is to write characters, and not bytes? PrintStream predates JDK 1.1 when Reader/Writer character streams were introduced. I imagine Sun would have deprecated PrintStream if only for the fact it is so widely used. (After all, you wouldn't want each call to System.out to generate a deprecated API warning! Also, changing the type from PrintStream to PrintWriter on the standard output streams would have broken existing applications.)
Since JDK 1.4 it's possible to specify the character encoding for a PrintStream. Thus, the differences between PrintStream and PrintWriter are only about auto flushing behavior and that a PrintStream cannot wrap a Writer.
So I made some code to test a theory, and it disproved my theory. Here it is:
import java.io.PrintWriter;
public class Main {
public static void main(String[] args) {
PrintWriter writer = new PrintWriter(System.out);
System.out.println("HI");
writer.println("HI");
writer.flush();
}
}Now here's the context for my question. I was taught that System.out is a stream object, and that the console grabs from the System.out stream and puts those contents on its stream. I was then taught that PrintWriter is an class that functions essentially identically to System.out, except that you can direct your destination stream. So I hypothesized, "If you made a PrintWriter object and sent the System.out stream in as its destination, would that be identical to just using System.out?
As it turns out, no, but I still don't fully understand why. What I do understand is that if I use the flush() method, it does essentially work the same. So my question is this:
When you use System.out.println() , does the method println() also tell the console to grab from the buffer so its not left in the System.out stream? And from the other perspective, when you use writer.println() (writer being the PrintWriter object in this context), does the println() method NOT tell the destination stream to grab from the buffer (until the flush() method is used)?
Any information helps, feel free to tell me that my interpretation is wrong or that my hypothesis is wrong. Or you can tell me anything really, tell me how your day is going. Any information helps, the more I know the better a programmer I can become :)
OutputStreams are meant for binary data. Writers (including PrintWriter) are meant for text data.
You may not see the difference in your specific situation as you're calling PrintWriter.write(int) which writes a single character - if the character encoding you're using just maps characters to the same byte, for characters less than 127, then you'll see the same result. But if you give it a different encoding, then you'll see a difference.
PrintWriter is also different in that it suppresses IO exceptions - as does PrintStream, which is the binary stream equivalent of PrintWriter.
From this java2novice.com link I extracted the following, that is similar to what Jon said:
ServletOutputStream: ServletResponse.getOutputStream() returns a ServletOutputStream
suitable for writing binary data in the response. The servlet
container does not encode the binary data, it sends the raw data
as it is.
PrintWriter: ServletResponse.getWriter() returns PrintWriter object which sends
character text to the client. The PrintWriter uses the character
encoding returned by getCharacterEncoding(). If the response's
character encoding has not been specified then it does default
character encoding.