0

If you use System.err.print("There was an error..."); System.error.flush(); do you need to flush System.out before hand. I know that writing with System.out.print("bla"); and System.error.print("bla"); can cause the unflushed streams to get mixed up.

I'm assuming that you would only need to do this if you know that there wasn't a System.out.println(); or System.out.print("\n"); because a "\n" automatically flushes in java.lang.System, but I just wanted to make sure.

Also, please don't say in the comments "Why didn't you just test it?" as it's a little hard to test this because you are relying on luck, essentially, to see whether the streams don't get flushed properly.

Thanks!

EDIT

Answer:

I guess just use Logger.getLogger(Your_Class.class.getName()).log(Level.WHATEVER, "message"); if there is no exception.

-

If you don't believe me that sout and serr get mixed up...

PROOF (class I just made):

package test;

/**
 *
 * @author dylnmc
 */
public class Test {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
            } else {
                System.err.println(i);
            }
        }
    }

}

output :

run:
0
1
3
2
4
6
8
10
12
14
16
18
5
7
9
11
13
15
17
19
BUILD SUCCESSFUL (total time: 0 seconds)

If you turn Test.java into jar and run java -jar file/to/jar/Test.jar pause there is no mismatch, though - as some people were saying (because this is a problem in most ide consoles).

-

-

Also, I still could not get the two different streams to flush in Netbeans ide; they were still all over the place.

dylnmc
  • 3,810
  • 4
  • 26
  • 42
  • 2
    What do you mean by "mixed up"? So stdout and stderr appear on the terminal in the precise order you've written to them in your Java app? *That* behavior is affected by other factors as well, e.g., an IDE console may behave differently than a system console. – Dave Newton Jul 16 '14 at 17:26
  • What are you using all this sysout and syserr printing for? Might it make more sense centralize this code in a single location so there's a single place to flush()? If this is for logging, consider using a logging framework instead of reinventing the wheel, e.g. java.util.logging. – Philipp Reichart Jul 16 '14 at 17:53
  • Printing out an error without throwing and Exception – dylnmc Jul 16 '14 at 17:56
  • Essentially, I'm writing a bunch of files, and if I cannot write to a particular file, I `System.err.println("Could not write to file " + file.getAbsolutePath()); System.error.flush()` and continue trying to write other files. – dylnmc Jul 16 '14 at 17:58
  • Is there a better way to achieve this? – dylnmc Jul 16 '14 at 17:58
  • You really want to look into logging, not random printlning and flushing of System.err/out: http://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html -- less code, no flushing and you can even get proper, non-truncated exception logging. – Philipp Reichart Jul 16 '14 at 17:59
  • I have a logger set up for the class, but no real predefined Exception, so I don't want to use a Logger either (although I could just leave out the third parameter). Good idea... Thanks – dylnmc Jul 16 '14 at 18:00

2 Answers2

0

System.out and System.err are two different streams of data. Writing to one normally does not alter the other. IDEs like Netbeans or Eclipse read both out and err streams and display both in the console window simultaneously. Data read from err stream might be highlighted in red. This makes it appear that output is "mixed up".

So, System.out.flush() will not have any effect on System.err. Instead, you might consider redirecting System.out to a separate stream using System.setOut, System.setErr and print the captured data just before exiting the program.

Gowtham
  • 1,465
  • 1
  • 15
  • 26
  • 1
    Nooooooooo... They're both output streams and you have to flush output streams or else they get jumbled. For the same reason that you cannot read a File with a BufferedReader or FileReader while a BufferedWriter or FileWriter (or whatever type of writer) has written to the text file and has not flushed explicitly (or implicitly with reader.close()), you cannot simply mix System.out.print() and System.err.print(). That is what I have read over and over again. Perhaps I am wrong. ? – dylnmc Jul 16 '14 at 17:55
  • @dylnmc The situation in case of reading/writing a single file is different - it includes a shared resource. But stdout and stderr are two different channels – Gowtham Jul 16 '14 at 18:09
  • I believe that is why you have to flush. I have seen this in action before. If you simply user sout and serr willy nilly without flush, then they become mixed up. – dylnmc Jul 16 '14 at 18:14
0

System.out.println(String s) and System.err.println(String s) are not atomic operations because they first print the string and then a newline. Atomicity is relative. The two operations (printing the string and printing the newline) are in a synchronized block, so they are atomic form the Java code point of view. However, they are still two separate operations for the underlying system. So, if the console is shared by err and out, the following code:

System.out.println("abc");
System.out.println("def");

will eventually result in "abc", "\n", "def", "\n" being printed in potentially incorrect order. The first newline will always be printed after "abc", and the second newline will always be printed after "def" (due to synchronization) but the sequence "abc", "def" "\n", "\n" is possible.

To avoid this, avoid using println:

System.out.print("abc" + "\n");
System.out.print("def" + "\n");

(Of course, you should use the correct line separator for your system.)

  • If "def" were printed to System.err then I'd understand the examples. I'd still be skeptical that println behaves differently to print with "\n". – Martin Dorey May 04 '22 at 20:53