Reputation: 1140
I'm trying to make a cross platform console progress indicator in Java. Therefore I use the System.out.printf method to print out a percentage:
System.out.printf("\t%2.2f%%\b\b\b\b\b\b", percentage);
and I place this in a for loop. The problem I encounter is that it's not printing anything until the whole for loop is done. This is a program example to show the problem:
public class Test {
public static void main(String[] args) {
for(int i =0; i<5000; i++){
System.out.printf("\b\b\b\b\b\b%2.2f%%", ((float) i/5000f)*100f);
System.out.flush();
}
}
}
I think the problem has something to do with compiler optimisation, but I'm not shure. The strange thing is that System.out.println
does print when the for loop is running.
Edit: I forgot to add it to the problem. But I had allready tried to flush the buffer. This makes no difference. Adding %n
to the end of my printf line works but it starts a newline, I really need it to reuse the current line.
All opposed solutions work. But they only work in real consoles. Not the netbeans or eclipse console.
Upvotes: 5
Views: 5974
Reputation: 21836
Try using Console instead:
for(int i =0; i<5000; i++){
System.console().format("\b\b\b\b\b\b%2.2f%%", ((float) i/5000f)*100f);
System.console().flush();
}
Upvotes: 0
Reputation: 46963
And once more the problem is with flushing the stream. Add this line after your printf
:
System.out.flush();
System.out.println
is flushing (much like C++'s << endl
). However, printf
is not flushing and is using buffer.
Upvotes: 2
Reputation: 500893
Add a call to flush()
:
for(int i =0; i<5000; i++){
System.out.printf("\b\b\b\b\b\b%2.2f%%", ((float) i/5000f)*100f);
System.out.flush();
}
Without the flush()
, the output gets accumulated in a buffer that only gets flushed once in a while (whenever it's full, or whenever a newline is printed).
The strange thing is that
System.out.println
does print when the for loop is running.
The reason for that is that the stream is line-buffered. This means that every newline triggers an implicit flush. The difference between your code and println()
is that the latter prints out a newline every time it's called.
Upvotes: 1
Reputation: 12006
That's because the output stream is line buffered. If you add a "%n" at the end of your format string you also generate a line break and the line will be flushed (i.e. printed). Alternatively call System.out.flush()
to manually flush the output stream and force buffered contents to be printed.
Upvotes: 7