2009-07-30 3 views
5

Bei Verwendung der Deflate-Methode von java.util.zip.Deflater muss ein Byte [] als Argument angegeben werden, wie groß soll dieses Byte [] initialisiert werden? Ich habe gelesen, dass es keine Garantie gibt, dass die komprimierten Daten sogar kleiner als die unkomprimierten Daten sind. Gibt es einen bestimmten Prozentsatz des Inputs, mit dem ich gehen sollte? Derzeit mache ich es doppelt so groß wie der EingangJava - Größe der Komprimierungsausgabe-ByteArray

Antwort

8

Nach dem Aufruf deflate, rufen Sie finished, um zu sehen, ob es noch mehr zu ausgeben hat. zB:

byte[] buffer = new byte[BUFFER_SIZE]; 
while (!deflater.finished()) { 
    int n = deflater.deflate(buffer); 
    // deal with the n bytes in out here 
} 

Wenn Sie wollen einfach nur alle Bytes im Speicher sammeln Sie eine ByteArrayOutputStream verwenden können. zB:

byte[] buffer = new byte[BUFFER_SIZE]; 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
while (!deflater.finished()) { 
    int n = deflater.deflate(buffer); 
    baos.write(buffer, 0, n); 
} 
return baos.toByteArray(); 
+2

Und wenn Sie mit einem riesigen Byte-Array wollen am Ende, einen 'ByteArrayOutputStream' außerhalb der Schleife erstellen, dann anhänge jede Iteration mit 'bos.append (out, 0, n)' –

+7

Danke für die Antwort. Ich verstehe es aber nicht ganz ... Muss ich Deflate() mehrmals aufrufen, bis die gesamte Eingabe komprimiert wurde? Und worauf sollte ich die BUFFER_SIZE einstellen? Gibt es irgendwo ein Tutorial oder etwas ähnliches, das das erklärt? danke – Clox

+1

Ich vermute, es gab eine Art von Race Condition, denn genau das ist der zweite Beispiel-Snippet, den ich gepostet habe. :-) –

6

Warum schreibt Java die Klasse als "deflater" falsch? Das Wort ist "Deflator". Meine Güte! Entschuldige, ich musste das von meiner Brust nehmen.

Wie bereits erwähnt, ist die erwartete Verwendung, deflate aufrufen, bis Sie die gesamte Ausgabe von der Komprimierung erhalten. Wenn Sie jedoch wirklich in einem einzigen Aufruf tun möchten, dann gibt es eine Grenze für den Betrag, um den deflate die Daten erweitern kann. Es gibt eine Funktion in zlib, die Java leider nicht zur Verfügung stellt, genannt deflateBound(), die diese obere Grenze zur Verfügung stellt. Sie können nur die konservative Aus dieser Funktion, mit der entsprechenden Zeile hier kopiert gebunden verwenden:

complen = sourceLen + 
      ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;