web-dev-qa-db-fra.com

Barre de progression de la ligne de commande en Java

J'ai un programme Java qui s'exécute en mode ligne de commande . Je voudrais afficher une barre de progression indiquant le pourcentage de travail effectué . Est-ce possible?

109
g andrieu

J'ai déjà implémenté ce genre de chose. Ce n'est pas tellement Java, mais quels caractères envoyer à la console.

La clé est la différence entre \n et \r.\n va au début d'une nouvelle ligne. Mais \r est juste retour chariot - il revient au début de la même ligne.

Il faut donc imprimer votre barre de progression, par exemple, en imprimant la chaîne

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

Au prochain tick de la barre de progression, écrasez la même ligne par une barre plus longue. (Comme nous utilisons\r, nous restons sur la même ligne) Par exemple:

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

Ce que vous devez vous rappeler de faire, c’est lorsque vous avez terminé, si vous imprimez

"done!\n"

Il se peut que vous ayez encore des déchets de la barre de progression sur la ligne. Donc, une fois que vous avez terminé avec la barre de progression, veillez à imprimer suffisamment d’espace pour le supprimer de la ligne. Tel que:

"done             |\n"

J'espère que cela pourra aider.

156
Matthias Wandel

Il y a https://github.com/ctongfei/progressbar , Licence: MIT

Barre de progression de la console simple. L'écriture de la barre de progression s'exécute maintenant sur un autre thread.

Menlo, Fira Mono, Code source Pro ou SF Mono sont recommandés pour des effets visuels optimaux.

Pour les polices Consolas ou Andale Mono, utilisez ProgressBarStyle.ASCII (voir ci-dessous) car les glyphes de dessin de boîte ne sont pas alignés correctement dans ces polices.

Maven:

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

Usage:

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

J'ai trouvé le code suivant pour fonctionner correctement. Il écrit des octets dans le tampon de sortie. Peut-être que les méthodes utilisant un écrivain tel que la méthode System.out.println() remplacent les occurrences de \r par \n pour correspondre à la fin de ligne native de la cible (si elle n'est pas configurée correctement). 

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);
        }
    }
}
21
keesj

J'ai fait un pourcentage de progression nu pour vérifier le reste du fichier à télécharger.

J'appelle la méthode périodiquement dans mon téléchargement de fichier pour vérifier la taille totale du fichier et le reste et le présente dans %.

Il peut également être utilisé pour d'autres tâches.

Test et exemple de sortie

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

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

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

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

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

Tester avec la boucle for

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

La méthode peut être facilement modifié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");
    }
}
5

Exemple C # mais je suppose que c'est la même chose pour System.out.print en Java . N'hésitez pas à me corriger si je me trompe.

En gros, vous voulez écrire le caractère d'échappement \r au début de votre message Le curseur retournera au début de la ligne (saut de ligne) sans passer à la ligne suivante.

    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

Voici une version modifiée de ce qui précède:

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

... et en général:

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

J'ai récemment rencontré le même problème, vous pouvez vérifier mon code:.

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

J'utilise une barre de progression "qui rebondit" lorsque je dois retarder un outil pour éviter une situation de concurrence critique.

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

Cela serait possible avec une bibliothèque Java Curses. Ceci est ce que j'ai trouvé. Je ne l'ai pas utilisé moi-même et je ne sais pas si c'est multi-plateforme.

2
kgiannakakis

Un peu de refactorisé et mis à jour la méthode de @ maytham-. Maintenant, il prend en charge une taille arbitraire de la barre de progression:

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