Java 中基于控制台的进度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1001290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:05:59  来源:igfitidea点击:

Console based progress in Java

javaconsoleprogress-barrefresh

提问by Monster

Is there are easy way to implement a rolling percentage for a process in Java, to be displayed in the console? I have a percentage data type (double) I generated during a particular process, but can I force it to the console window and have it refresh, instead of just printing a new line for each new update to the percentage? I was thinking about pushing a cls and updating, because I'm working in a Windows environment, but I was hoping Java had some sort of built-in capability. All suggestions welcomed! Thanks!

是否有简单的方法可以在 Java 中实现进程的滚动百分比,以显示在控制台中?我有一个在特定过程中生成的百分比数据类型(double),但是我可以将它强制到控制台窗口并刷新它,而不是仅仅为百分比的每个新更新打印一个新行吗?我正在考虑推送 cls 和更新,因为我在 Windows 环境中工作,但我希望 Java 具有某种内置功能。欢迎所有建议!谢谢!

采纳答案by laalto

You can print a carriage return \rto put the cursor back to the beginning of line.

您可以打印回车符\r将光标放回行首。

Example:

例子:

public class ProgressDemo {
  static void updateProgress(double progressPercentage) {
    final int width = 50; // progress bar width in chars

    System.out.print("\r[");
    int i = 0;
    for (; i <= (int)(progressPercentage*width); i++) {
      System.out.print(".");
    }
    for (; i < width; i++) {
      System.out.print(" ");
    }
    System.out.print("]");
  }

  public static void main(String[] args) {
    try {
      for (double progressPercentage = 0.0; progressPercentage < 1.0; progressPercentage += 0.01) {
        updateProgress(progressPercentage);
        Thread.sleep(20);
      }
    } catch (InterruptedException e) {}
  }
}

回答by Glen

I don't think there's a built-in capability to do what you're looking for.

我认为没有内置的功能可以做你正在寻找的东西。

There is a library that will do it (JLine).

有一个库可以做到这一点(JLine)。

See this tutorial

看这个教程

回答by David Johnstone

I'm quite sure there is no way to change anything that the console has already printed because Java considers the console (standard out) to be a PrintStream.

我很确定没有办法更改控制台已经打印的任何内容,因为 Java 将控制台(标准输出)视为 PrintStream。

回答by Tom Jefferys

Don't know about anything built in to java itself, but you can use terminal control codes to do things like reposition the cursor. Some details here: http://www.termsys.demon.co.uk/vtansi.htm

不知道 java 本身内置的任何内容,但您可以使用终端控制代码来执行诸如重新定位光标之类的操作。这里有一些细节:http: //www.termsys.demon.co.uk/vtansi.htm

回答by Thejesh GN

Clear the console by running the os specific command and then print the new percentage

通过运行 os 特定命令清除控制台,然后打印新的百分比

回答by Tongfei Chen

I have written such a package in Java.

我已经用 Java 编写了这样一个包。

https://github.com/ctongfei/progressbar

https://github.com/ctongfei/progressbar

回答by Mike Shauneu

I use following code:

我使用以下代码:

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(current == 0 ? (int) (Math.log10(total)) : (int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
        .append(String.format(" %d/%d, ETA: %s", current, total, etaHms));

    System.out.print(string);
}

The result: enter image description here

结果: 在此处输入图片说明

回答by Elphara77

import java.util.Random;

public class ConsoleProgress {

    private static String CURSOR_STRING = "0%.......10%.......20%.......30%.......40%.......50%.......60%.......70%.......80%.......90%.....100%";

    private static final double MAX_STEP = CURSOR_STRING.length() - 1;

    private double max;
    private double step;
    private double cursor;
    private double lastCursor;

    public static void main(String[] args) throws InterruptedException {
        // ---------------------------------------------------------------------------------
        int max = new Random().nextInt(400) + 1;
        // ---------------------------------------------------------------------------------
        // Example of use :
        // ---------------------------------------------------------------------------------
        ConsoleProgress progress = new ConsoleProgress("Progress (" + max + ") : ", max);
        for (int i = 1; i <= max; i++, progress.nextProgress()) {
            Thread.sleep(3L); // a task with no prints
        }
    }

    public ConsoleProgress(String title, int maxCounts) {
        cursor = 0.;
        max = maxCounts;
        step = MAX_STEP / max;
        System.out.print(title);
        printCursor();
        nextProgress();
    }

    public void nextProgress() {
        printCursor();
        cursor += step;
    }

    private void printCursor() {
        int intCursor = (int) Math.round(cursor) + 1;
        System.out.print(CURSOR_STRING.substring((int) lastCursor, intCursor));
        if (lastCursor != intCursor && intCursor == CURSOR_STRING.length())
            System.out.println(); // final print
        lastCursor = intCursor;
    }
}

回答by victorantunes

Late for the party, but here's an answer:

聚会迟到了,但这是一个答案:

public static String getSingleLineProgress(double progress) {
    String progressOutput = "Progress: |";
    String padding = Strings.padEnd("", (int) Math.ceil(progress / 5), '=');
    progressOutput += Strings.padEnd(padding, 0, ' ') + df.format(progress) + "%|\r";
    if (progress == 100.0D) {
        progressOutput += "\n";
    }
    return progressOutput;
}

Remember to use System.out.print()instead of System.out.println()

记得用System.out.print()代替System.out.println()