web-dev-qa-db-fra.com

Progression basée sur la console en Java

Existe-t-il un moyen simple d'implémenter un pourcentage glissant pour un processus en Java, à afficher dans la console? J'ai généré un type de données en pourcentage (double) au cours d'un processus particulier, mais puis-je le forcer dans la fenêtre de la console et l'actualiser au lieu d'imprimer une nouvelle ligne pour chaque nouvelle mise à jour du pourcentage? Je pensais pousser des clés et mettre à jour, parce que je travaille dans un environnement Windows, mais j'espérais que Java avait une sorte de fonctionnalité intégrée. Toutes les suggestions sont les bienvenues! Merci!

33
Monster

Vous pouvez imprimer un retour chariot \r pour ramener le curseur au début de la ligne.

Exemple:

public class ProgressDemo {
  static void updateProgress(double progressPercentage) {
    final int width = 50; // progress bar width in chars

    System.out.print("\r[");
    int i = 0;
    for (; i <= (int)(progressPercentage*width); i++) {
      System.out.print(".");
    }
    for (; i < width; i++) {
      System.out.print(" ");
    }
    System.out.print("]");
  }

  public static void main(String[] args) {
    try {
      for (double progressPercentage = 0.0; progressPercentage < 1.0; progressPercentage += 0.01) {
        updateProgress(progressPercentage);
        Thread.sleep(20);
      }
    } catch (InterruptedException e) {}
  }
}
52
laalto

J'utilise le code suivant: 

public static void main(String[] args) {
    long total = 235;
    long startTime = System.currentTimeMillis();

    for (int i = 1; i <= total; i = i + 3) {
        try {
            Thread.sleep(50);
            printProgress(startTime, total, i);
        } catch (InterruptedException e) {
        }
    }
}


private static void printProgress(long startTime, long total, long current) {
    long eta = current == 0 ? 0 : 
        (total - current) * (System.currentTimeMillis() - startTime) / current;

    String etaHms = current == 0 ? "N/A" : 
            String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
                    TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
                    TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));

    StringBuilder string = new StringBuilder(140);   
    int percent = (int) (current * 100 / total);
    string
        .append('\r')
        .append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
        .append(String.format(" %d%% [", percent))
        .append(String.join("", Collections.nCopies(percent, "=")))
        .append('>')
        .append(String.join("", Collections.nCopies(100 - percent, " ")))
        .append(']')
        .append(String.join("", Collections.nCopies(current == 0 ? (int) (Math.log10(total)) : (int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
        .append(String.format(" %d/%d, ETA: %s", current, total, etaHms));

    System.out.print(string);
}

Le résultat:  enter image description here

9
Mike Shauneu

J'ai écrit un tel paquet en Java.

https://github.com/ctongfei/progressbar

7
Tongfei Chen

Je ne pense pas qu'il existe une capacité intégrée pour faire ce que vous cherchez. 

Il y a une bibliothèque qui le fera (JLine). 

Voir ce tutorial

6
Glen

Je suis presque sûr qu'il n'y a aucun moyen de changer quoi que ce soit que la console a déjà imprimé car Java considère que la console (sortie standard) est un PrintStream.

4
David Johnstone

Vous ne connaissez rien de Java, mais vous pouvez utiliser des codes de contrôle de terminal pour repositionner le curseur. Quelques détails ici: http://www.termsys.demon.co.uk/vtansi.htm

2
Tom Jefferys

En retard pour la fête, mais voici une réponse:

public static String getSingleLineProgress(double progress) {
    String progressOutput = "Progress: |";
    String padding = Strings.padEnd("", (int) Math.ceil(progress / 5), '=');
    progressOutput += Strings.padEnd(padding, 0, ' ') + df.format(progress) + "%|\r";
    if (progress == 100.0D) {
        progressOutput += "\n";
    }
    return progressOutput;
}

N'oubliez pas d'utiliser System.out.print() au lieu de System.out.println()

0
victorantunes

Effacez la console en exécutant la commande spécifique au système d'exploitation, puis imprimez le nouveau pourcentage.

0
Thejesh GN
import Java.util.Random;

public class ConsoleProgress {

    private static String CURSOR_STRING = "0%.......10%.......20%.......30%.......40%.......50%.......60%.......70%.......80%.......90%.....100%";

    private static final double MAX_STEP = CURSOR_STRING.length() - 1;

    private double max;
    private double step;
    private double cursor;
    private double lastCursor;

    public static void main(String[] args) throws InterruptedException {
        // ---------------------------------------------------------------------------------
        int max = new Random().nextInt(400) + 1;
        // ---------------------------------------------------------------------------------
        // Example of use :
        // ---------------------------------------------------------------------------------
        ConsoleProgress progress = new ConsoleProgress("Progress (" + max + ") : ", max);
        for (int i = 1; i <= max; i++, progress.nextProgress()) {
            Thread.sleep(3L); // a task with no prints
        }
    }

    public ConsoleProgress(String title, int maxCounts) {
        cursor = 0.;
        max = maxCounts;
        step = MAX_STEP / max;
        System.out.print(title);
        printCursor();
        nextProgress();
    }

    public void nextProgress() {
        printCursor();
        cursor += step;
    }

    private void printCursor() {
        int intCursor = (int) Math.round(cursor) + 1;
        System.out.print(CURSOR_STRING.substring((int) lastCursor, intCursor));
        if (lastCursor != intCursor && intCursor == CURSOR_STRING.length())
            System.out.println(); // final print
        lastCursor = intCursor;
    }
}
0
Elphara77