2014-02-25 20 views
6

Ich habe ein Problem sehr ähnlich unten auf den Link:BufferedInputStream ByteArrayOutputStream sehr langsam

PDF to byte array and vice versa

Der Hauptunterschied ist, ich eine Socket-Verbindung über einen Serversocket Binary enthält, anstatt eine Datei zu interpretieren versuchen . Dies funktioniert wie erwartet.

jedoch das Problem, das ich habe, ist, dass dieser Prozess eine recht lange Zeit nimmt in den Speicher zu lesen, etwa 1 Minute und 30 Sekunden für 500 Byte (obwohl die Größe der einzelnen Strom massiv variieren)

Hier mein Code:

BufferedInputStream input = new BufferedInputStream(theSocket.getInputStream()); 
byte[] buffer = new byte[8192]; 
int bytesRead; 
ByteArrayOutputStream output = new ByteArrayOutputStream(); 

while ((bytesRead = input.read(buffer)) != -1) 
{ 
    output.write(buffer, 0, bytesRead); 
} 

byte[] outputBytes = output.toByteArray(); 

//Continue ... and eventually close inputstream 

Wenn ich log es Fortschritte in der while-Schleife innerhalb des Terminals scheint es ziemlich schnell alle Bytes protokolliert (dh erreicht das Ende des Streams), scheint aber dann Pause für eine Zeit, bevor Sie aus der While-Schleife ausbrechen und fortfahren.

Hoffnung, die Sinn macht.

+0

Schließt der Server die Verbindung? Was Sie beschreiben, sieht so aus, als würde der Stream blockieren und auf weitere Bytes warten. –

Antwort

5

Nun, Sie lesen, bis der Sockel geschlossen ist, im Grunde - das ist, wenn read -1 zurückgibt.

Also meine Vermutung ist, dass das andere Ende der Verbindung es für 90 Sekunden geöffnet hält, bevor es geschlossen wird. Beheben Sie das und Sie werden Ihr Problem beheben.

+1

Und wenn Sie keine Kontrolle über das andere Ende der Verbindung haben, können Sie versuchen, ein Timeout für den Socket zu setzen: 'theSocket.setSoTimeout (10000); // 10s Socket Timeout' – Vlad

+0

Das macht Sinn. Ich nahm an, dass -1 bedeutet, dass alle Informationen empfangen wurden, nicht dass der Socket abgelaufen war. Mein Problem ist, dass es keine Möglichkeit gibt zu sagen, wann das 'Ende des Socket-Streams' ist, dh es gibt keine feste Größe oder Byte am Ende des Streams um das 'Ende' anzuzeigen – D4y

+0

@ D4y: Genau - es ist nur ein Stream von Daten. Wenn Sie ein protokollbasiertes Protokoll wünschen (z. B. über Längen- oder Nachrichtenende), müssen Sie das in sich selbst eintragen. –

0
ByteArrayOutputStream(int size); 

standardmäßig die Größe ist 32 Byte, so dass es wie folgt increses: 32-> 64-> 128-> 256 -> ... So initialisieren es mit einer größeren Kapazität.

0

Sie können festlegen, wie lange es dauert, Daten zwischen einem BufferedInputStream und einem ByteArrayOutputStream zu kopieren.

int size = 256 << 20; // 256 MB 
ByteArrayInputStream bais = new ByteArrayInputStream(new byte[size]); 
long start = System.nanoTime(); 
BufferedInputStream input = new BufferedInputStream(bais); 
byte[] buffer = new byte[8192]; 
int bytesRead; 
ByteArrayOutputStream output = new ByteArrayOutputStream(); 

while ((bytesRead = input.read(buffer)) != -1) { 
    output.write(buffer, 0, bytesRead); 
} 

byte[] outputBytes = output.toByteArray(); 
long time = System.nanoTime() - start; 
System.out.printf("Took %.3f seconds to copy %,d MB %n", time/1e9, size >> 20); 

druckt

Took 0.365 seconds to copy 256 MB 

Es wird für kleinere Nachrichten heißt < < 256 MB viel schneller sein.