2017-04-14 1 views
1

Ich zeige den Fortschritt in der Konsole an und benutze das '\ r' Zeichen, um die Zeile zwischen den einzelnen Aktualisierungen zu löschen, as per this answer.Wagenrücklauf ' r' nicht zuverlässig, wenn die Konsole häufig aktualisiert wird

public class MainTest { 
    public static int delay = 10; 

    public static void main(String[] args) { 
     for (int i = 0; i <= 100; i++) { 
      System.out.print("\r"); 
      System.out.print("process:" + i + "%"); 
      Thread.sleep(delay); 
     } 
    } 
} 

Mit einer Verzögerung von 240 ms oder mehr scheint es gut zu funktionieren. Sobald ich jedoch darunter gehe, ist der '\ r' Charakter nicht zuverlässig. Es sieht nervös und nicht immer die Linie löschen, so dass am Ende Sie

process:97%process:98%process:99%process:100% 

This gif zeigen den Unterschied zwischen Update Geschwindigkeiten zu sehen. Ich möchte nicht, dass mein Programm langsamer läuft, nur damit die Konsolenausgabe gut aussieht. Wie kann ich das beheben?

+0

brauche Hilfe, wie es zu beheben, möchte ich einen Fortschritt in der Java-Konsole. – doublez

+0

Für zukünftige Referenz, fügen Sie bitte den Code als Teil Ihrer Frage ein. Sie werden viel eher Hilfe bei Ihren Fragen bekommen, wenn Sie das tun. –

Antwort

0

Eine Option besteht darin, Ihren Code in zwei Threads aufzuteilen, die parallel ausgeführt werden. Ihr Worker-Thread führt alle Ihre Arbeitslogik aus und aktualisiert eine Fortschrittsvariable. Von Zeit zu Zeit liest Ihr UIhread den Fortschritt und zeigt ihn in der Konsole an.

import java.util.concurrent.atomic.AtomicInteger; 

public class HelloWorld 
{ 
    public static void main(String[] args) throws InterruptedException 
    { 
     final AtomicInteger progress = new AtomicInteger(0); 

     Thread worker = new Thread(new Runnable() { 
      public void run() { 
       for (int i = 0; i <= 100; i++) { 
        try { 
         // Do some work here 
         Thread.sleep(1); 
         progress.set(i); 
        } catch (InterruptedException e) { 
         progress.set(100); 
        } 
       } 
      } 
     }); 

     worker.start(); 

     while (progress.get() < 100) { 
      // Now you can choose how often to update the console, without 
      // slowing down your worker. 
      Thread.sleep(240); 
      System.out.print("\r"); 
      System.out.print("Progress: " + progress.get() + "%"); 
     } 

     worker.join(); 
    } 
} 

Es ist sehr häufig für den UI-Code auf einem separaten Thread auf die Anwendungslogik ausgeführt werden, meist so, dass, wenn etwas zu lange dauert, ist es den Benutzer nicht stoppt aus der Interaktion - sie können Klicken Sie immer noch in der Nähe, wechseln Sie zwischen den Tabs, etc.

+0

"Thread.sleep (240);", wenn Sie unter 240 gehen, wie 20ms, 10ms in der IDE-Konsole finden Sie es nicht zuverlässig, aber in der Linux-Shell funktioniert es gut. Ich weiß nicht, was andere Leute tun, wie '\ b'. – doublez

+0

Ja, der Punkt dieses Codes ist, dass Sie eine beliebige Aktualisierungshäufigkeit wählen können, ohne dass dies Auswirkungen auf die Ausführungsgeschwindigkeit Ihres Arbeiters hat. Es ist jedoch eine ziemlich willkürliche Wahl - selbst wenn Sie einen 1-Sekunden-Schlaf gewählt haben, haben Sie möglicherweise immer noch das gleiche Problem auf langsamen Computern. Dies ist die beste Lösung, die ich mir vorstellen kann. –

Verwandte Themen