2016-05-22 3 views
1

Ich mache ein Kopier-Einfüge-Programm für die Übung. Was ich bemerkte ist, dass die Aktualisierung der UI im while Betrieb der I/O, drossle ich die Übertragungsgeschwindigkeit bis zu 40%. Was 4 Sekunden nahm jetzt 8.Java I/O Loop-Drosselung aufgrund von UI-Updates

Zum Beispiel kopieren nimmt:

int b; 
long total = 0; 
byte[] buf = new byte[4096]; 
while ((b = in.read(buf)) != -1) { 
     out.write(buf, 0, b); 
     ui.setSoFar(total); 
     total += b; 
} 

Die ui.setSoFar() nur ruft die setText() Methode auf einem JLabel in einem JFrame

Die out und in Vars sind ein FileInputStream und FileOutputStream.

Mit einem Kingston SHF37A/120G gedrosselt auf SATA II-Geschwindigkeiten dauert das Kopieren einer 313MB-Datei etwa 8 Sekunden, was etwa 40 MB/s entspricht.

Wenn ich den Code ändern, wie folgt aussehen:

int b; 
byte[] buf = new byte[4096]; 
while ((b = in.read(buf)) != -1) { 
     out.write(buf, 0, b); 
} 

, die eine einfache Schleife ist, nichts in-zwischen den Lese- und Schreib, eine 313MB-Datei Kopieren dauert etwa 3 Sekunden, die 100 MB/s ist .

Das ist fast ein Unterschied von 60% bei der Ausgabe!

Wie zu lösen, damit ich noch eine UI aktualisieren und die 100% Übertragungsgeschwindigkeit beibehalten kann, nicht verlieren die 60%?

+3

Nun, mit 40MB/s und Aktualisieren der Benutzeroberfläche alle 4096 Bytes, aktualisieren Sie die Benutzeroberfläche etwa 10'000 mal pro Sekunde - niemand ist so schnell die Benutzeroberfläche lesen gegangen. Versuchen Sie, die Benutzeroberfläche weniger häufig zu aktualisieren (möglicherweise alle 400'000 Bytes) –

+0

Nun, die Puffergröße ist gestiegen, die Frage ist, gibt es irgendwelche Nebenwirkungen? Es ist jetzt wesentlich schneller tho. Vielen Dank. – Gala

+0

Dies ist ein guter Kandidat für die Verwendung von [SwingWorker] (https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingWorker.html). – VGR

Antwort

1

Sie müssen Multithreading verwenden. Aktualisieren Sie die Benutzeroberfläche in einem anderen Thread. Dieser Thread muss Ihren Kopiervorgang überprüfen (Sie benötigen dafür eine Variable und Sie aktualisieren sie in Ihrer while-Schleife). Im UI-Thread überprüfen Sie alle paar Sekunden diese Variable und aktualisieren den JFrame.