Java printf未打印输出

5

我正在尝试使用Java制作一个跨平台的控制台进度指示器。因此我使用System.out.printf方法打印出一个百分比:

System.out.printf("\t%2.2f%%\b\b\b\b\b\b", percentage);

我把代码放在了一个for循环中,但是遇到的问题是只有整个循环结束后才打印出结果。以下是代码示例:

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

我认为这个问题与编译器优化有关,但我不确定。奇怪的是,当for循环正在运行时,System.out.println确实会打印。
编辑:我忘记将其添加到问题中。但我已经尝试过刷新缓冲区。这没有任何区别。在我的printf行末尾添加%n可以解决问题,但它会开始一个新行,我真的需要重用当前行。
所有反对的解决方案都有效。但它们只适用于真正的控制台,而不是NetBeans或Eclipse控制台。

你的代码对我来说可以运行,但速度有点快,所以我加入了 try { Thread.sleep (10); } catch (InterruptedException ignored) {} - user unknown
4个回答

7

这是因为输出流是按行缓冲的。如果在格式字符串的末尾添加“%n”,还会生成一个换行符并刷新该行(即打印)。或者调用System.out.flush()手动刷新输出流,强制缓冲内容被打印。


感谢您的清除提示! - Tom Swifty

2

问题在于清空流。在你的printf之后添加这行代码:

System.out.flush();

System.out.println 是刷新输出流的操作(类似于 C++ 的 << endl)。然而,printf 不会刷新输出流,而是使用缓冲区。


Flush是一个方法,所以你肯定需要括号。 - Boris Strandjev
我在原始代码中添加了括号,但似乎它们没有被复制。我已经在起始帖子中修复了这个问题。然而问题仍未解决。 - Daan Pape
替换旧字符为新字符的目标是什么,以便获得类似于计数器的东西? - Boris Strandjev
我想制作一个进度指示器。当我有大约5000个步骤要计算时,我不想打印出5000行,而只想显示一行,显示已经处理了多少百分比。 - Daan Pape
谢谢您的帮助。事实证明,这是由于NetBeans控制台未像普通控制台一样响应。 - Daan Pape
你应该尝试一下Eclipse控制台。我不得不使用命令行来测试你的代码。 - Boris Strandjev

1
在程序中添加一个调用 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();
    }

没有flush(),输出会累积在缓冲区中,只有在缓冲区满时或打印换行符时才会刷新。

奇怪的是,在 for 循环运行时,System.out.println 确实会输出。

原因是流是行缓冲的。这意味着每个新行都会触发隐式刷新。你的代码和 println() 之间的区别在于后者每次被调用时都会打印一个新行。


0
尝试使用控制台代替:
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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接