55

Why do certain streams need to be flushed (FileOutputStream and streams from Sockets) while the standard output stream does not?

Every time someone uses the System.out PrintStream object, be it while calling println() or write(), they never flush the stream. However, other programmers habitually call flush() a PrintStream/PrintWriter with other streams.

I've recently asked this question to several programmers and some believe that there is some background handling in Java to auto-flush the System.out stream but I can't find any documentation on that.

Something like this makes me wonder if simply calling System.out.println() is platform independent as some systems may need you to flush the stream.

Mike Samuel
  • 109,453
  • 27
  • 204
  • 234
Mark Nguyen
  • 657
  • 1
  • 5
  • 7

4 Answers4

54

System.out is based around a PrintStream which by default flushes whenever a newline is written.

From the javadoc:

autoFlush - A boolean; if true, the output buffer will be flushed whenever a byte array is written, one of the println methods is invoked, or a newline character or byte ('\n') is written

So the println case you mention is explicitly handled, and the write case with a byte[] is also guaranteed to flush because it falls under "whenever a byte array is written".

If you replace System.out using System.setOut and don't use an autoflushing stream, then you will have to flush it like any other stream.

Library code probably shouldn't be using System.out directly, but if it does, then it should be careful to flush because a library user might override System.out to use a non flushing stream.

Any Java program that writes binary output to System.out should be careful to flush before exit because binary output often does not include a trailing newline.

Mike Samuel
  • 109,453
  • 27
  • 204
  • 234
  • 4
    only valid `if true`, but is it? I could not find any documentation about the value of autoFlush for System.out... – user85421 Aug 23 '11 at 19:53
  • 1
    @Carlos, It is up to the system that bootstraps the JVM and launches the main class what `System.out` and `System.err` are bound to and how they flush. When you use the `java` binary to launch a class `System.out` is initialized to something like `new PrintStream(new FileOutputStream(FileDescriptor.out), true, System.getProperty("file.encoding"))` but other JVMs differ. Obviously a JVM that embeds applets does something different. – Mike Samuel Aug 23 '11 at 20:46
  • @MikeSamuel, So does it mean that we still *need* to flush anyway since the autoflush behavior is not **guaranteed** by the specs? – Pacerier Jun 18 '14 at 11:10
  • @Pacerier, There's nothing in the `System.{out,err}` docs saying they must be autoflushing but most Java programs assume they are so few VMs are going to startup without that being the case, but flushing manually sounds like a good idea if you're delivering the program output or important logging or auditing telemetry via them. – Mike Samuel Jun 18 '14 at 11:58
  • 1
    Flushing implicitly with `'\n'` or explicitly with `.flush()` works for Windows `cmd` but not for the `mintty` (aka. MSYS2 Terminal) for Windows. – veganaiZe Feb 03 '19 at 17:57
  • @veganaiZe Do you need to write a `"\r\n"` for that? I.e. does writing `System.lineSeparator()` and then flushing work consistently? – Mike Samuel Feb 05 '19 at 19:32
  • @MikeSamuel I've tried that and every combo that I can think up. I think it's a bug in `mintty` for Windows. – veganaiZe Feb 12 '19 at 19:54
  • @MikeSamuel It's a known issue for ALL programs compiled outside of Cygwin/MSYS environment. (MinGW != MSYS) https://github.com/mintty/mintty/wiki/Tips#inputoutput-interaction-with-alien-programs – veganaiZe Feb 13 '19 at 17:45
  • @veganaiZe, nice. – Mike Samuel Feb 13 '19 at 20:41
6

From the PrintStream documentation:

Optionally, a PrintStream can be created so as to flush automatically; this means that the flush method is automatically invoked after a byte array is written, one of the println methods is invoked, or a newline character or byte ('\n') is written.

Although I don't see it mentioned explicitly in the documentation, it's my understanding that System.out will perform this auto-flushing.

David Z
  • 116,302
  • 26
  • 230
  • 268
4

When you can't wait for the item to be displayed, flush the stream.

When the JVM goes down, not flushing the stream risks the item being lost in the display buffer, which might make the sensible error message telling you why the JVM went down lost forever. That makes debugging much more difficult, as people then tend to say, "but it didn't get here, because it would have printed this".

Edwin Buck
  • 64,804
  • 7
  • 90
  • 127
2

System.out is by default line-buffered. So if you are calling println and not print it should not be a problem. See this article for more info.

1ac0
  • 2,695
  • 2
  • 29
  • 46
Connor Doyle
  • 1,752
  • 13
  • 20