Java'da komut satırı ilerleme çubuğu


130

Komut satırı modunda çalışan bir Java programım var. Yapılan işin yüzdesini gösteren bir ilerleme çubuğu görüntülemek istiyorum. Unix altında wget kullanırken görebileceğiniz türden bir ilerleme çubuğu. Mümkün mü?


Sorunuzun cevabını bilmiyorum, ancak bu soruda bahsedilen kitaplıkları kontrol ederek başlayabilirsiniz: stackoverflow.com/questions/435740/…
Jonik

Teşekkürler. Bahsedilen kitaplıklar, konsolda görüntülemek yerine komut satırı bağımsız değişkeninin ayrıştırılmasıyla ilgili daha çok şey var. Yine de teşekkürler.
g andrieu

7
Bu konu üzerine. OP mümkünse, kütüphane önerisi için değil (en azından mevcut düzenlemede) sorar
Neil McGuigan

Bu kodu stackoverflow.com/questions/1001290/… deniyorum ve çalışıyor! (Yalnızca terminalde doğru çalıştırma, Eclipse'de kullanmayın)
Wendel

Yanıtlar:


177

Bu tür şeyleri daha önce uyguladım. Çok fazla java değil, konsola hangi karakterlerin gönderileceği.

Anahtar arasındaki farktır \nve \r. \nyeni bir satırın başlangıcına gider. Ama \rsadece satır başıdır - aynı satırın başlangıcına geri döner.

Yani yapılacak şey, örneğin dizeyi yazdırarak ilerleme çubuğunuzu yazdırmaktır.

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

İlerleme çubuğunun bir sonraki onayında, aynı satırın üzerine daha uzun bir çubuk yazın. (\ r kullandığımız için aynı satırda kalıyoruz) Örneğin:

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

Yapmayı hatırlamanız gereken şey, bittiğinde, o zaman sadece yazdırırsanız

"done!\n"

Hattaki ilerleme çubuğundan hala biraz çöp olabilir. Bu nedenle, ilerleme çubuğunu tamamladıktan sonra, satırdan kaldırmak için yeterli boşluk yazdırdığınızdan emin olun. Gibi:

"done             |\n"

Umarım yardımcı olur.


Bu gerçekten çapraz platform mu? Muhtemelen Windows ve Linux'ta iyi davranacaktır, peki ya Mac'ler? Bende yok, bu yüzden deneyemiyorum ...
Radu Murzea

2
@RaduMurzea OS X bir * NIX işletim sistemidir, bu nedenle Linux'ta çalışıyorsa, OS X üzerinde çalışacaktır (bu her şey için doğru değil, ama burada doğru).
bfontaine

3
Teşekkürler! Ancak bu ant ile çalışmaz (hem linux hem de osx üzerinde denendi; java'yı doğrudan çağırırken iyi çalışıyor). Herhangi bir fikri olan var mı?
user495285

Bunun konsolda yerleşik olan tutulmada çalışmadığını unutmayın (en azından benim için). Ancak bu bir geliştirme konsolu olduğu için bu çok da önemli olmamalı.
Qw3ry


46

Orada https://github.com/ctongfei/progressbar Lisans: MİT

Basit konsol ilerleme çubuğu. İlerleme çubuğu yazma artık başka bir iş parçacığında çalışıyor.

En iyi görsel efektler için Menlo, Fira Mono, Source Code Pro veya SF Mono önerilir.

Consolas veya Andale Mono yazı tipleri için, ProgressBarStyle.ASCIIbu yazı tiplerinde kutu çizimi glifleri düzgün hizalanmadığından kullanın (aşağıya bakın).

Uzman:

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

Kullanımı:

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

1
bu düzgün görünüyor ve CLI'mde bulunan birkaç yüz dizgi tampon satırını değiştirmeme izin verecek. Peki ya "tıklamalar" arasında dakikalarca çalışan bir uygulamam varsa ( step()aramalar arasındaki dakikalar )? Kitaplığınız zaman uyumsuz olarak çalışarak saatin güncellenmesine izin veriyor mu? Ya kütüphanem günlerce çalışırsa? O kullanıyor mu /rstratejisini? Bu multi-yüz megabayt çıktıyla sonuçlanacak mı?
Groostav

23

Aşağıdaki kodun doğru çalıştığını buldum. Baytları çıktı tamponuna yazar. Belki de bu yöntem gibi bir yazıcı kullanan yöntemler , hedefin yerel satır sonuyla eşleşecek şekilde için System.out.println()oluşumlarının yerini alır (doğru şekilde yapılandırılmamışsa).\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);
        }
    }
}

7

Kalan indirme dosyasını kontrol etmek için yüzde bir ilerleme kaydettim.

Toplam dosya boyutunu kontrol etmek ve kalan ve bunu sunmak için dosya indirmemde düzenli olarak yöntemi çağırıyorum %.

Diğer görev amaçları için de kullanılabilir.

Test ve çıktı örneği

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

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

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

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

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

For döngüsü ile test edin

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

Yöntem kolayca değiştirilebilir:

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

5

C # Örnek ama bunun System.out.printJava için de aynı olduğunu varsayıyorum . Yanılıyorsam beni düzeltmekten çekinmeyin.

Temel olarak, mesajınızın başına \rkaçış karakterini yazmak istersiniz, bu da imlecin sonraki satıra geçmeden satırın başına (Satır Besleme) dönmesine neden olur.

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

    }

Güzel örnek, kesinlikle yardımcı olacaktır. Teşekkürler.
g andrieu

Güzel! Teşekkür ederim. Büyüleyici gibi çalışır. Okuması kolay. Lovely
kholofelo Maloma

4

Biraz yeniden düzenlenmiş ve güncellenmiş @ maytham-ɯɐɥʇʎɐɯ yöntemi. Şimdi, ilerleme çubuğunun keyfi bir boyutunu destekliyor:

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

3

İşte yukarıdakilerin değiştirilmiş bir versiyonu:

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

... ve esas olarak:

loading("Calculating ...");

2

Bu bir Java Curses kütüphanesi ile mümkün olabilir. Bu Bulduğum şeydir. Ben kendim kullanmadım ve çapraz platform olup olmadığını bilmiyorum.


Küfürler, ihtiyacım olan kolay kullanım için biraz ek yük olabilir, ancak bu kesinlikle bir yol. Teşekkürler.
g andrieu

2

Bir yarış durumunu önlemek için bir aracı geciktirmem gerektiğinde "sıçrayan" bir ilerleme çubuğu kullanıyorum.

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

Son zamanlarda aynı problemle karşılaştım, kodumu kontrol edebilirsiniz: Daha sonra değiştirebileceğiniz% 5 üzerinde bir # için ayarladım.

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

1
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

Eoin Campbell'ın kodunu java olarak düzenledim ve yüzde olarak biçimlendirilmiş ilerleme ekledim.

public static String progressBar(int currentValue, int maxValue) {
    int progressBarLength = 33; //
    if (progressBarLength < 9 || progressBarLength % 2 == 0) {
        throw new ArithmeticException("formattedPercent.length() = 9! + even number of chars (one for each side)");
    }
    int currentProgressBarIndex = (int) Math.ceil(((double) progressBarLength / maxValue) * currentValue);
    String formattedPercent = String.format(" %5.1f %% ", (100 * currentProgressBarIndex) / (double) progressBarLength);
    int percentStartIndex = ((progressBarLength - formattedPercent.length()) / 2);

    StringBuilder sb = new StringBuilder();
    sb.append("[");
    for (int progressBarIndex = 0; progressBarIndex < progressBarLength; progressBarIndex++) {
        if (progressBarIndex <= percentStartIndex - 1
        ||  progressBarIndex >= percentStartIndex + formattedPercent.length()) {
            sb.append(currentProgressBarIndex <= progressBarIndex ? " " : "=");
        } else if (progressBarIndex == percentStartIndex) {
            sb.append(formattedPercent);
        }
    }
    sb.append("]");
    return sb.toString();
}

int max = 22;
System.out.println("Generating report...");
for (int i = 0; i <= max; i++) {
   Thread.sleep(100);
   System.out.print(String.format("\r%s", progressBar(i, max)));
}
System.out.println("\nSuccessfully saved 32128 bytes");

Ve çıktı:

Generating report...

[========      24.2 %             ]

[============  45.5 %             ]

[============  78.8 % =====       ]

[============  87.9 % ========    ]

[============ 100.0 % ============]

Successfully saved 32128 bytes

0
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
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
static String progressBar(int progressBarSize, long currentPosition, long startPositoin, long finishPosition) {
    String bar = "";
    int nPositions = progressBarSize;
    char pb = '░';
    char stat = '█';
    for (int p = 0; p < nPositions; p++) {
        bar += pb;
    }
    int ststus = (int) (100 * (currentPosition - startPositoin) / (finishPosition - startPositoin));
    int move = (nPositions * ststus) / 100;
    return "[" + bar.substring(0, move).replace(pb, stat) + ststus + "%" + bar.substring(move, bar.length()) + "]";
}

görüntü açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.