Java:在不使用新行的情况下更新命令行中的文本

Java:在不使用新行的情况下更新命令行中的文本,java,console,console-application,Java,Console,Console Application,我想在命令行Java程序中添加一个进度指示器 例如,如果我正在使用wget,它会显示: 71% [===========================> ] 358,756,352 51.2M/s eta 3s 是否有可能在不向底部添加新行的情况下更新进度指示器 谢谢。首先,当你写作时,不要使用writeln()。使用write()。第二,您可以使用“\r”来回车,而不使用新行。回车应该放在行的开头。我使用以下代码: public static void main

我想在命令行Java程序中添加一个进度指示器

例如,如果我正在使用wget,它会显示:

71% [===========================>           ] 358,756,352 51.2M/s  eta 3s
是否有可能在不向底部添加新行的情况下更新进度指示器


谢谢。

首先,当你写作时,不要使用writeln()。使用write()。第二,您可以使用“\r”来回车,而不使用新行。回车应该放在行的开头。

我使用以下代码:

public static void main(String[] args) {
    long total = 235;
    long startTime = System.currentTimeMillis();

    for (int i = 1; i <= total; i = i + 3) {
        try {
            Thread.sleep(50);
            printProgress(startTime, total, i);
        } catch (InterruptedException e) {
        }
    }
}


private static void printProgress(long startTime, long total, long current) {
    long eta = current == 0 ? 0 : 
        (total - current) * (System.currentTimeMillis() - startTime) / current;

    String etaHms = current == 0 ? "N/A" : 
            String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
                    TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
                    TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));

    StringBuilder string = new StringBuilder(140);   
    int percent = (int) (current * 100 / total);
    string
        .append('\r')
        .append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
        .append(String.format(" %d%% [", percent))
        .append(String.join("", Collections.nCopies(percent, "=")))
        .append('>')
        .append(String.join("", Collections.nCopies(100 - percent, " ")))
        .append(']')
        .append(String.join("", Collections.nCopies((int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
        .append(String.format(" %d/%d, ETA: %s", current, total, etaHms));

    System.out.print(string);
}
publicstaticvoidmain(字符串[]args){
长期总计=235;
long startTime=System.currentTimeMillis();

对于(int i=1;i,但如果文本长度可能缩短(例如,显示ETA所需的位数减少),请记住在旧字符上写空格,以便它们不再显示。编辑:此外,请记住执行System.out.flush()以确保文本实际显示(例如,在线路缓冲终端上)。我使用了
\r
,但它的行为类似于
\n
。我使用的是
打印
而不是
println
。知道它为什么不工作吗?@CardinalSystem-可能使用eclipse控制台吗?显然它处理不正确。\r不过它在java cli中可以工作。@newsha啊,似乎是这样。谢谢!@rfeak Sorry,我在Eclipse中尝试了这一点,但它会将每个进度打印到新行上。我在System.out.print(字符串)之前添加了以下命令;它修复了这个问题:System.out.println(新字符串(新字符[70])。replace(“\0”,“\r\n”));基本上,这会清除Eclipse控制台,所以看起来这行代码正在更新。@PhDeveloper是的,Eclipse被破坏了。在关于控制台的100篇文章中,你会发现一条注释:“在每个终端上都能工作,但Eclipse除外”。我有相当大的值(字节文件上载),所以不是
int%=(int)(当前*100/total)
为了避免整数溢出,我不得不使用
整数百分比=(int)((float)current/(float)total)*100);
来避免整数溢出。这取决于终端窗口的大小吗??