Java 中的命令行进度条

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/852665/
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 20:11:42  来源:igfitidea点击:

Command line progress bar in Java

javacommand-lineprogress-bar

提问by g andrieu

I have a Java program running in command line mode. I would like to display a progress bar, showing the percentage of job done. The same kind of progress bar you would see using wget under unix. Is this possible?

我有一个在命令行模式下运行的 Java 程序。我想显示一个进度条,显示完成工作的百分比。在 unix 下使用 wget 会看到相同类型的进度条。这可能吗?

采纳答案by Matthias Wandel

I have implemented this sort of thing before. Its not so much about java, but what characters to send to the console.

我以前实施过这种事情。它不是关于java,而是发送到控制台的字符。

The key is the difference between \nand \r. \ngoes to the start of a new line. But \ris just carriage return- it goes back to the start of the same line.

关键的区别是\n\r\n转到新行的开头。但\r只是回车- 它回到同一行的开头。

So the thing to do is to print your progress bar, for example, by printing the string

所以要做的是打印你的进度条,例如,通过打印字符串

"|========        |\r"

On the next tick of the progress bar, overwrite the same line with a longer bar. (because we are using \r, we stay on the same line) For example:

在进度条的下一个刻度上,用更长的进度条覆盖同一行。(因为我们使用的是\r,所以我们保持在同一行)例如:

"|=========       |\r"

What you have to remember to do, is when done, if you then just print

你必须记住要做的是,完成后,如果你只是打印

"done!\n"

You may still have some garbage from the progress bar on the line. So after you are done with the progress bar, be sure to print enough whitespace to remove it from the line. Such as:

你可能还有一些来自进度条的垃圾就行了。所以在你完成进度条后,一定要打印足够的空白以将其从行中删除。如:

"done             |\n"

Hope that helps.

希望有帮助。

回答by kgiannakakis

This would be possible with a Java Curses library. Thisis what I have found. I haven't used it myself and I don't know if it is cross-platform.

这可以通过 Java Curses 库实现。是我发现的。我自己没用过,不知道是不是跨平台的。

回答by Eoin Campbell

C# Example but I'm assuming this is the same for System.out.printin Java. Feel free to correct me if I'm wrong.

C# 示例,但我假设这System.out.print在 Java 中是相同的。如果我错了,请随时纠正我。

Basically, you want to write out the \rescape character to the start of your message which will cause the cursor to return to the start of the line (Line Feed) without moving to the next line.

基本上,您希望\r在消息的开头写出转义字符,这将导致光标返回到行首(换行)而不移动到下一行。

    static string DisplayBar(int i)
    {
        StringBuilder sb = new StringBuilder();

        int x = i / 2;
        sb.Append("|");
        for (int k = 0; k < 50; k++)
            sb.AppendFormat("{0}", ((x <= k) ? " " : "="));
        sb.Append("|");

        return sb.ToString();
    }

    static void Main(string[] args)
    {
        for (int i = 0; i <= 100; i++)
        {
            System.Threading.Thread.Sleep(200);
            Console.Write("\r{0} {1}% Done", DisplayBar(i), i);
        }

        Console.ReadLine();

    }

回答by keesj

I found the following code to work correctly. It writes bytes to the output buffer. Perhaps that methods using a writer like the System.out.println()method replaces the occurrences of \rto \nto match the target's native line ending(if not configured properly).

我发现以下代码可以正常工作。它将字节写入输出缓冲区。也许使用像该System.out.println()方法这样的编写器的方法会替换\rto的出现\n以匹配目标的本机行结尾(如果配置不正确)。

public class Main{
    public static void main(String[] arg) throws Exception {
        String anim= "|/-\";
        for (int x =0 ; x < 100 ; x++) {
            String data = "\r" + anim.charAt(x % anim.length()) + " " + x;
            System.out.write(data.getBytes());
            Thread.sleep(100);
        }
    }
}

回答by mkeathley

I use a "bouncing" progress bar when I need to delay a tool to prevent a race condition.

当我需要延迟工具以防止竞争条件时,我会使用“弹跳”进度条。

private void delay(long milliseconds) {
    String bar = "[--------------------]";
    String icon = "%";

    long startTime = new Date().getTime();
    boolean bouncePositive = true;
    int barPosition = 0;

    while((new Date().getTime() - startTime) < milliseconds) {
        if(barPosition < bar.length() && barPosition > 0) {
            String b1 = bar.substring(0, barPosition);
            String b2 = bar.substring(barPosition);
            System.out.print("\r Delaying: " + b1 + icon + b2);
            if(bouncePositive) barPosition++;
            else barPosition--;
        } if(barPosition == bar.length()) {
            barPosition--;
            bouncePositive = false;
        } if(barPosition == 0) {
            barPosition++;
            bouncePositive = true;
        }

        try { Thread.sleep(100); }
        catch (Exception e) {}
    }
    System.out.print("\n");
}

回答by user3563245

Here is a modified version of the above:

这是上述内容的修改版本:

private static boolean loading = true;
private static synchronized void loading(String msg) throws IOException, InterruptedException {
    System.out.println(msg);
    Thread th = new Thread() {
        @Override
        public void run() {
            try {
                System.out.write("\r|".getBytes());
                while(loading) {
                    System.out.write("-".getBytes());
                    Thread.sleep(500);
                }
                System.out.write("| Done \r\n".getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    th.start();
}

... and in main:

...主要是:

loading("Calculating ...");

回答by maytham-???????

I have made a percentage progress bare to check the remain download file.

我已经取得了一个百分比的进展来检查剩余的下载文件。

I call the method periodically in my file download to check the total file-size and remaining and present that in %.

我在我的文件下载中定期调用该方法以检查总文件大小和剩余大小并将其呈现在%.

It can be used for other task purpose as well.

它也可以用于其他任务目的。

Test and output example

测试和输出示例

progressPercentage(0, 1000);
[----------] 0%

progressPercentage(10, 100);
[*---------] 10%

progressPercentage(500000, 1000000);
[*****-----] 50%

progressPercentage(90, 100);
[*********-] 90%

progressPercentage(1000, 1000);
[**********] 100%

Test with for loop

用 for 循环测试

for (int i = 0; i <= 200; i = i + 20) {
    progressPercentage(i, 200);
    try {
        Thread.sleep(500);
    } catch (Exception e) {
    }
}

The method can be easily modified:

该方法可以很容易地修改:

public static void progressPercentage(int remain, int total) {
    if (remain > total) {
        throw new IllegalArgumentException();
    }
    int maxBareSize = 10; // 10unit for 100%
    int remainProcent = ((100 * remain) / total) / maxBareSize;
    char defaultChar = '-';
    String icon = "*";
    String bare = new String(new char[maxBareSize]).replace('
public static void main(String[] argv) throws Exception{


    System.out.write("\r".getBytes());
    int percentage =10;
    while(percentage <= 100) {
        String temp =generateStars(percentage);
        System.out.write(temp.getBytes());
        System.out.print("\b\b\b");
        percentage = percentage+10;
        Thread.sleep(500);
    }
}

    public static String generateStars(int percentage)
    {
        int startsNum = percentage / 4;
        StringBuilder builder = new StringBuilder();
        while(startsNum >= 0)
        {
        builder.append("*");
        startsNum--;
        }
        builder.append(percentage+"%");
        return builder.toString();
    }
', defaultChar) + "]"; StringBuilder bareDone = new StringBuilder(); bareDone.append("["); for (int i = 0; i < remainProcent; i++) { bareDone.append(icon); } String bareRemain = bare.substring(remainProcent, bare.length()); System.out.print("\r" + bareDone + bareRemain + " " + remainProcent * 10 + "%"); if (remain == total) { System.out.print("\n"); } }

回答by vootla561

public static void main (String[] args) throws java.lang.Exception
{
    int i = 0;
    while(i < 21) {
        System.out.print("[");
        for (int j=0;j<i;j++) {
            System.out.print("#");
        }

        for (int j=0;j<20-i;j++) {
            System.out.print(" ");
        }

        System.out.print("] "+  i*5 + "%");
        if(i<20) {
            System.out.print("\r");
            Thread.sleep(300);
        }
        i++;
    }
    System.out.println();
}

回答by Aashutosh Rathi

I have recently faced the same problem, you can check my code: I have set it for one # on 5%, which you can modify later.

我最近遇到了同样的问题,你可以查看我的代码:我已经将它设置为 5% 的一个 #,你可以稍后修改。

<dependency>
  <groupId>me.tongfei</groupId>
  <artifactId>progressbar</artifactId>
  <version>0.5.5</version>
</dependency>

回答by koppor

There is https://github.com/ctongfei/progressbar, License: MIT

https://github.com/ctongfei/progressbar,许可证:麻省理工学院

Simple console progress bar. Progress bar writing now runs on another thread.

简单的控制台进度条。进度条写入现在在另一个线程上运行。

Menlo, Fira Mono, Source Code Pro or SF Mono are recommended for optimal visual effects.

推荐使用 Menlo、Fira Mono、Source Code Pro 或 SF Mono 以获得最佳视觉效果。

For Consolas or Andale Mono fonts, use ProgressBarStyle.ASCII(see below) because the box-drawing glyphs are not aligned properly in these fonts.

对于 Consolas 或 Andale Mono 字体,请使用ProgressBarStyle.ASCII(见下文),因为框绘图字形在这些字体中未正确对齐。

Maven:

马文:

ProgressBar pb = new ProgressBar("Test", 100); // name, initial max
 // Use ProgressBar("Test", 100, ProgressBarStyle.ASCII) if you want ASCII output style
pb.start(); // the progress bar starts timing
// Or you could combine these two lines like this:
//   ProgressBar pb = new ProgressBar("Test", 100).start();
some loop {
  ...
  pb.step(); // step by 1
  pb.stepBy(n); // step by n
  ...
  pb.stepTo(n); // step directly to n
  ...
  pb.maxHint(n);
  // reset the max of this progress bar as n. This may be useful when the program
  // gets new information about the current progress.
  // Can set n to be less than zero: this means that this progress bar would become
  // indefinite: the max would be unknown.
  ...
  pb.setExtraMessage("Reading..."); // Set extra message to display at the end of the bar
}
pb.stop() // stops the progress bar

Usage:

用法:

##代码##