Java中的命令行进度条

g a*_*ieu 121 java command-line progress-bar

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

Mat*_*del 166

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

关键的区别是\n\r. \n进入新线的开始.但\r只是回车 - 它会回到同一行的开头.

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

"|========        |\r"
Run Code Online (Sandbox Code Playgroud)

在进度条的下一个刻度线上,用较长的条覆盖同一行.(因为我们正在使用\ r,我们保持在同一条线上)例如:

"|=========       |\r"
Run Code Online (Sandbox Code Playgroud)

你需要记住的是,如果你刚刚打印,那么什么时候完成

"done!\n"
Run Code Online (Sandbox Code Playgroud)

您可能仍然会从该行的进度条中获得一些垃圾.因此,在完成进度条之后,请务必打印足够的空格以将其从行中删除.如:

"done             |\n"
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 谢谢!但是这不适用于ant(在linux和osx上都试过;在直接调用java时工作正常).有人有什么想法? (3认同)
  • @RaduMurzea OS X是一个*NIX操作系统,所以如果它适用于Linux,它将适用于OS X(对于所有事情都不是这样,但这里的确如此). (2认同)

kop*_*por 34

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

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

建议使用Menlo,Fira Mono,Source Code Pro或SF Mono以获得最佳视觉效果.

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

Maven的:

<dependency>
  <groupId>me.tongfei</groupId>
  <artifactId>progressbar</artifactId>
  <version>0.5.5</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

用法:

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
Run Code Online (Sandbox Code Playgroud)

  • 这看起来很整洁,它可以让我替换 CLI 上的几百个字符串缓冲区行。但是,如果我有一个应用程序在“滴答声”之间运行几分钟(`step()` 调用之间的分钟)呢?您的库是否异步运行,从而允许时钟更新?如果我的图书馆运行了好几天怎么办?它是否使用`/r` 策略?这会导致数百兆字节的输出吗? (2认同)

小智 23

我发现以下代码可以正常工作.它将字节写入输出缓冲区.也许使用像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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


may*_*ʎɐɯ 7

我已经取得了百分比的进展,以检查剩余的下载文件.

我在我的文件下载中定期调用该方法来检查总文件大小并保留并显示在其中%.

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

测试和输出示例

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

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

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

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

progressPercentage(1000, 1000);
[**********] 100%
Run Code Online (Sandbox Code Playgroud)

用for循环测试

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

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

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('\0', 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");
    }
}
Run Code Online (Sandbox Code Playgroud)


Eoi*_*ell 5

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

基本上,您希望将\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();

    }
Run Code Online (Sandbox Code Playgroud)


Den*_*nis 5

稍微重构和更新了 @maytham-\xc9\xaf\xc9\x90\xc9\xa5\xca\x87\xca\x8e\xc9\x90\xc9\xaf \ 的方法。现在它支持任意大小的进度条:

\n\n
    public static void progressPercentage(int done, int total) {\n        int size = 5;\n        String iconLeftBoundary = "[";\n        String iconDone = "=";\n        String iconRemain = ".";\n        String iconRightBoundary = "]";\n\n        if (done > total) {\n            throw new IllegalArgumentException();\n        }\n        int donePercents = (100 * done) / total;\n        int doneLength = size * donePercents / 100;\n\n        StringBuilder bar = new StringBuilder(iconLeftBoundary);\n        for (int i = 0; i < size; i++) {\n            if (i < doneLength) {\n                bar.append(iconDone);\n            } else {\n                bar.append(iconRemain);\n            }\n        }\n        bar.append(iconRightBoundary);\n\n        System.out.print("\\r" + bar + " " + donePercents + "%");\n\n        if (done == total) {\n            System.out.print("\\n");\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n