2011-01-01 15 views
23

Vorrei aggiungere un indicatore di avanzamento a un programma Java da riga di comando.Java: aggiornamento del testo nella riga di comando senza una nuova riga

Per esempio, se sto usando wget, si vede:

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

E 'possibile avere un indicatore di progresso che gli aggiornamenti senza l'aggiunta di una nuova linea per il fondo?

Grazie.

+0

@rfeak Siamo spiacenti, http://stackoverflow.com/questions/1001290/console-based-progress-in-java – TheLQ

risposta

27

Prima di scrivere, non utilizzare writeln(). Usa write(). In secondo luogo, puoi utilizzare "\ r" per Ritorno a capo senza usare \ n che è una nuova riga. Il ritorno a capo dovrebbe riportarti all'inizio della riga.

+7

Ma se la lunghezza del testo può eventualmente ridursi (ad esempio, il numero di cifre richieste per visualizzare l'ETA diminuisce), ricorda di scrivere spazi sui vecchi caratteri in modo che non vengano più visualizzati. EDIT: Inoltre, ricorda di eseguire System.out.flush() per assicurarti che il testo venga effettivamente visualizzato (ad esempio su un terminale bufferizzato in linea). – jstanley

+0

@jstanley - Buoni punti da ricordare. – rfeak

23

Io uso seguente codice:

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

Il risultato: enter image description here

Problemi correlati