System.out not flushing

2019-09-05 18:11发布

问题:

I have a java application that takes input via a Scanner reading System.in, and gives output via System.out. The scanner is always active, it does not terminate without using Ctrl+C via the terminal or ending the process in an IDE.

I'm running into some behavior that leads me to believe System.out is not flushing properly.

In my code there are the lines:

System.out.print(",\\" + '\n');
System.out.print("     " + someString); 

(someString does not contain a newline character)

When I execute this code via the terminal, the whitespace and someString are not printed to the terminal. However in my IDE's console, it is. (IntelliJ)

If I change the second statement to println instead of print, it works fine, but it does append a new line between one execution of the code and the next, which is not workable here. (Maybe there's something I can do with a carriage return?)

This sounds a lot like the output isn't being flushed, as its only System.out.print that has the trouble. However, adding System.out.flush() after the print statement does not cause it to print.

回答1:

This sounds a lot like the output isn't being flushed, as its only System.out.print that has the trouble.

Typically System.out and System.err are configured differently. (System.err is typically not buffered, and System.out is typically buffered.) However, the javadocs do not specify the flushing behavior of either streams. This could explain the differences in behavior between the (real) console and running in an IDE.

For info, here is how the streams are initialized in Java 8:

    FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
    FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
    FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
    setIn0(new BufferedInputStream(fdIn));
    setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
    setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));

private static PrintStream  ewPrintStream(FileOutputStream fos, String enc) {
   if (enc != null) {
        try {
            return new PrintStream(new BufferedOutputStream(fos, 128),
                                   true, enc);
        } catch (UnsupportedEncodingException uee) {}
    }
    return new PrintStream(new BufferedOutputStream(fos, 128), true);
}

As you can see, System.out is initialized as buffered with autoflush enabled.


However, adding System.out.flush() after the print statement does not cause it to print.

Are you sure about that? A flush() should flush any buffered output.

I suggest that the problem is actually somewhere else; e.g. the print or flush calls are not happening ... for some reason.


It is also possible that some of your problems are due to this:

System.out.print(",\\" + '\n');

As @javaguy points out, a newline character is a platform specific line separator. On some platforms, the console requires something different. The simplest platform independent way to tell the console to do a line break is:

System.out.println(",\\");

Or putting it all together:

System.out.println(",\\");
System.out.print("     " + someString); 
System.out.flush();   // This is necessary ... and should work.


回答2:

Assuming that you are running the program in Windows, the carriage return (\r) and line feed (\n) together need to be added to print the new line as below:

System.out.print(",\\" + '\r\n');
System.out.print("     " + someString); 


回答3:

System.out.println() places the cursor to the next line after execution. so you don't need to add "\n". That's probably why a line of space is between the lines.

Just do this:

System.out.println(",\\");
System.out.println("     " + someString);