web-dev-qa-db-ja.com

Javaのコマンドラインプログレスバー

Javaコマンドラインモードで実行中のプログラムがあります。完了したジョブの割合を示すプログレスバーを表示したいと思います。これは可能ですか?

120
g andrieu

私は以前にこの種のことを実装しました。 Javaについてはそれほどではありませんが、コンソールに送信する文字は何ですか。

重要なのは、\n\rの違いです。 \nは新しい行の先頭に移動します。しかし、\rは単なるキャリッジリターンです。同じ行の先頭に戻ります。

そのため、たとえば、文字列を印刷することにより、進行状況バーを印刷します

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

進行状況バーの次の目盛りで、同じ行を長いバーで上書きします。 (\ rを使用しているため、同じ行に留まります)例:

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

覚えておく必要があるのは、完了したら、印刷するだけです

"done!\n"

行の進行状況バーにまだゴミがある可能性があります。そのため、プログレスバーの操作が完了したら、行から削除するのに十分な空白を印刷してください。といった:

"done             |\n"

お役に立てば幸いです。

162
Matthias Wandel

https://github.com/ctongfei/progressbar 、ライセンス:MITがあります

シンプルなコンソールプログレスバー。進行状況バーの書き込みが別のスレッドで実行されるようになりました。

最適な視覚効果を得るには、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>

使用法:

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
33
koppor

次のコードが正しく機能することがわかりました。出力バッファにバイトを書き込みます。おそらく、System.out.println()メソッドのようなライターを使用するメソッドは、\rから\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);
        }
    }
}
23
keesj

残りのダウンロードファイルを確認するために、進捗状況をむき出しにしています。

ファイルのダウンロードで定期的にこのメソッドを呼び出して、合計ファイルサイズと残りを確認し、%

他のタスクの目的にも使用できます。

テストと出力の例

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

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

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

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

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

Forループでテストする

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

メソッドは簡単に変更できます。

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

C#の例ですが、これはJavaのSystem.out.printでも同じと仮定しています。私が間違っているなら、私を修正してください。

基本的に、メッセージの先頭に\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();

    }
5
Eoin Campbell

上記の修正版は次のとおりです。

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

...そして主に:

loading("Calculating ...");
3
user3563245

私は最近同じ問題に直面しました。あなたは私のコードを確認することができます:私はそれを5%の1つに設定しました。

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

競合状態を防ぐためにツールを遅延させる必要がある場合は、「バウンス」プログレスバーを使用します。

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");
}
2
mkeathley

これは、Java Cursesライブラリで可能です。 これ は、私が見つけたものです。 -プラットフォーム。

2
kgiannakakis
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();
    }
1
vootla561

@maytham-ɯɐɥʇʎɐɯのメソッドを少しリファクタリングして更新しました。現在、任意のサイズのプログレスバーをサポートしています。

    public static void progressPercentage(int done, int total) {
        int size = 5;
        String iconLeftBoundary = "[";
        String iconDone = "=";
        String iconRemain = ".";
        String iconRightBoundary = "]";

        if (done > total) {
            throw new IllegalArgumentException();
        }
        int donePercents = (100 * done) / total;
        int doneLength = size * donePercents / 100;

        StringBuilder bar = new StringBuilder(iconLeftBoundary);
        for (int i = 0; i < size; i++) {
            if (i < doneLength) {
                bar.append(iconDone);
            } else {
                bar.append(iconRemain);
            }
        }
        bar.append(iconRightBoundary);

        System.out.print("\r" + bar + " " + donePercents + "%");

        if (done == total) {
            System.out.print("\n");
        }
    }
1
Dennis
public class Main {

    public static void main(String[] args) throws Exception {

        System.out.println("Loading : ");
            int count =1;
            for(int j=1;j<150;j++){

                System.out.print("\r");
                if(count==1){
                    System.out.print("/");
                    count++;
                }
                else if(count==2){
                    System.out.print("|");
                    count++;
                }
                else if(count==3){
                    System.out.print("-");
                    count++;
                }
                else if(count==4){
                    System.out.print("\\");
                    count++;
                }
                else if(count==5){
                    System.out.print("|");
                    count++;
                }
                else
                    count = 1;
            Thread.sleep(200);
        }

        }

    }
0
Arun Joshla
public class ProgressBar
{
    private int max;

    public ProgressBar(int max0) {
        max = max0;
        update(0);
    }

    public void update(int perc) {
        String toPrint = "|";
        for(int i = 0; i < max; i++) {
            if(i <= (perc + 1))
                toPrint += "=";
            else
                toPrint += " ";
        }

        if(perc >= max)
            Console.print("\r");
        else
            Console.print(toPrint + "|\r");
    }
}
0
Deplover