• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Rob Spoor
  • Devaka Cooray
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • Tim Holloway
Bartenders:
  • Jj Roberts
  • Al Hobbs
  • Piet Souris

PrintStream versus PrintWriter

 
Saloon Keeper
Posts: 1609
52
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So learning about PrintStream and PrintWriter, I casually noticed that most lean towards PrintWriter, but was left wondering when would I actually care about PrintStream.

I posted some guesses based on the few things I saw that you could do with PrintStream and not PrintWriter, basically, you could also write out "raw bytes" as well, but I didn't see a great use case for doing that.

This dude isn't super-popular, he seems to get as many 👎 as 👍, probably because he doesn't have slick graphics, music, animations, etc. but he comes right out and answers my question like I just raised my hand and asked it:
https://ramj2ee.blogspot.com/2016/08/java-tutorial-java-io-printwriter_16.html

The only PrintStream objects you are likely to need are System.out and System.err

When you need to create a formatted output stream, instantiate PrintWriter, not PrintStream.



Only then does he go into all the stuff they have in common, which everyone does right away, but left me wondering "So when do I actually need to instantiate PrintStream?"

It seems the answer is:

System.out and System.err are famous already existing PrintStream objects you might well need to use, like, almost every time you called println() in your first 200 programs.
if you ever needed another one, you'd probably know it.
If you are instantiating something, PrintWriter is your guy.



I like this direct advice.  If he copied it from somewhere, I haven't seen it, just lots of things that show both and then seem to lean towards PrintWriter without telling you not to worry about instantiating PrintStream objects in the future.
 
Marshal
Posts: 26909
82
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My impression is that PrintStream (first seen in Java in 1.0) was a mistake. From the beginning the rule in Java I/O was that a Writer would convert between chars (in the code) and bytes (in the external environment), whereas a Stream would only traffic in bytes. So having a PrintStream which used an encoding (old name) or charset (new name) to map chars to bytes would have been an embarrassment. Hence PrintWriter, which did essentially the same things, appeared in Java 1.1.

But of course by then they couldn't change System.out to be a PrintWriter instead of a PrintStream. All they could do was to change the documentation of PrintStream to say "Probably don't use this class. Really, just use PrintWriter instead."
 
Master Rancher
Posts: 4052
56
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:But of course by then they couldn't change System.out to be a PrintWriter instead of a PrintStream.


Well, they could have.  But, they were Sun.
 
Jesse Silverman
Saloon Keeper
Posts: 1609
52
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Last question on this specific topic.

Is there ever a reason to wrap System.out or System.err in a PrintWriter instead of just using them as a PrintStream, since they were "born this way"?

I think there may be due to this Constructor:
PrintWriter​(OutputStream out, boolean autoFlush, Charset charset)
Creates a new PrintWriter from an existing OutputStream.

It looks like it could help you escape from "The Tyranny of Default Charset (encoding)" but that also seems dangerous or that it might not work (because you should never change horse encodings in the middle of a Stream), in which case it would always be pointless to do so.

If that works correctly, maybe you would want to do it sometimes.  Then there would be a question of whether it costs a lot to do so.

Looking at code examples on the Web seems worse than useless at this point.  Everyone understands the general idea of IOStreams, but confusion on the particular details seems to be beyond rife.
 
Mike Simmons
Master Rancher
Posts: 4052
56
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, I can imagine a situation where it makes sense to wrap System.out or System.in in a Writer or Reader.  You might be using (or writing) a general use library that wants a Writer or Reader for its I/O... and then in some case, you want to pipe System.out or System.in in as the source of that I/O.  This also makes it easier to write unit tests - it's easy to test code that does output to an arbitrary Writer; harder to test if it writes to System.out.  Though it's often even easier to write and test something that accepts a String for input and returns a String for output.  But yes, wrapping standard I/O in a Reader or Writer is certainly possible.
 
Saloon Keeper
Posts: 24501
167
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've been doing it for years.

I have been writing code for multiple platforms for a very long time. One of my most amusing projects required me (per the contract) to create a system using the Commodore Amiga (a 32-bit bytewise-continuous system) to be run on MS-DOS (16-bit bytewisr-discontinuous system).  So I did.

I'm not going to use low-level interfaces when there are higher-level services that are better suited. A lot of my system portability comes from that extra layer of abstraction. In the case of text I/O, in particular, I'm staying as far away from code that requires manual fiddling with CR, CR/LF, or LF as end-of-line characters depending on the OS and when I'm intending to Read or Write as opposed to brute-force I/O, I'm going to use Readers and Writers in preference to raw Streams.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic