2

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.

sudom82
  • 135
  • 2
  • 12
  • I'm not really sure what the question is, but `System.out` doesn't specify it's auto-flushing behaviour; so it's up to the implementation. Apparently in your particular setup, IntelliJ's and whatever JAVA_HOME is set to (guessing usage) differ. – BeUndead Oct 29 '16 at 03:30
  • That may be the case. I've tried it on both windows and linux computers with the same problem, they all have the same versions of the JDK. – sudom82 Oct 29 '16 at 03:38
  • @Sudom82 Did you try adding '\r\n' as in my answer ? – Vasu Oct 29 '16 at 03:50

3 Answers3

2

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.
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • I have verified the System.out.flush() is being called via a code coverage tool. I'll double check this though. – sudom82 Oct 29 '16 at 03:32
  • A code coverage tool is not going to give the correct answer. It will tell you that the method is called *somewhere*, not that it is called at the *particular place you are interested in*. (The flush method is called under the hood when a newline is written, for example.) – Stephen C Oct 29 '16 at 03:44
  • Well, I'm only running a single test of this one method, and my code coverage tool shows this exact line with System.out.flush(); is being executed, along with the line before and the line after. I may be misunderstanding it, but if so I don't know how. – sudom82 Oct 29 '16 at 04:06
  • Well, like I said, a newline will trigger a flush ... and you are outputting a newline. A better way to figure out what is going one would be to use a debugger, and set a breakpoint on the `PrintStream.flush()` method. That will tell you where and when `flush()` is actually being called. – Stephen C Oct 29 '16 at 04:08
  • I'll give your debugger suggestion a go. Thanks for the help everyone. I'll report back if I figure it out. – sudom82 Oct 29 '16 at 04:25
0

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); 
Vasu
  • 21,832
  • 11
  • 51
  • 67
  • This is beside the point. Autoflushing occurs based on the presence of a newline (`'\n'`) character. – Stephen C Oct 29 '16 at 03:42
  • @StephenC I think his question is 'someString does not contain a newline character' (if run from Terminal), so adding \r\n should solve the problem. – Vasu Oct 29 '16 at 03:50
  • @javaguy Just tried your suggestion, assuming that those should be double quotes around \r\n on line 1 (otherwise there's a compiler error). Unfortunately it didn't fix the problem. someString is still not printed until another new line (through println or print('\n')) is called, if ever. – sudom82 Oct 29 '16 at 04:01
0

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); 
TotallyGamerJet
  • 339
  • 1
  • 2
  • 12
  • This does print all the output, but it adds an empty new line in between executions of the code, which makes it not a good option for me. – sudom82 Oct 29 '16 at 03:45