5

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.

1
  • Your code works for me, but is a bit fast, so I included a try { Thread.sleep (10); } catch (InterruptedException ignored) {}. Commented Mar 24, 2012 at 16:52

4 Answers 4

7

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

6 Comments

Flush is method so you need brackets for sure.
I had added brackets in my original code, I see they were not copied. I fixed it in the starting post. The problem is still not solved.
and what is the goal to replace the old characters with the new ones so you get something similar to counter?
I want to make a progress indicator. When I have like 5000 steps to calculate I don't want to print out 5000 lines but only one line showing the percentage of how much has been processed allready.
Thank you for the help. It turns out it was the console from netbeans that didn't respond as a normal console.
|
1

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.

Comments

0

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();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.