2011-01-01 3 views
23

Je voudrais ajouter un indicateur de progression à un programme Java en ligne de commande.Java: Mise à jour du texte dans la ligne de commande sans nouvelle ligne

Par exemple, si j'utilise wget, il montre:

71% [===========================>   ] 358,756,352 51.2M/s eta 3s 

Est-il possible d'avoir un indicateur de progression que les mises à jour sans ajouter une nouvelle ligne au fond?

Merci.

+0

@rfeak Désolé, http://stackoverflow.com/questions/1001290/console-based-progress-in-java – TheLQ

Répondre

27

Lorsque vous écrivez, n'utilisez pas writeln(). Utilisez write(). Deuxièmement, vous pouvez utiliser un "\ r" pour retourner le chariot sans utiliser \ n qui est une nouvelle ligne. Le retour chariot devrait vous replacer au début de la ligne.

+7

Mais si la longueur du texte peut éventuellement diminuer (par exemple, le nombre de chiffres requis pour afficher l'ETA diminue), n'oubliez pas d'écrire des espaces sur les anciens caractères afin qu'ils ne s'affichent plus. EDIT: En outre, n'oubliez pas de faire System.out.flush() pour vous assurer que le texte s'affiche réellement (par exemple sur un terminal à ligne tampon). – jstanley

+0

@jstanley - De bons points à retenir. – rfeak

23

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

Questions connexes