Schlechte Performance der Java unzip Dienstprogramme
Habe ich bemerkt, dass der unzip-Anlage in Java ist sehr langsam im Vergleich zur Verwendung einer nativen tool wie WinZip.
Gibt es eine Drittanbieter-Bibliothek für Java, die effizienter ist?
Open Source bevorzugt.
Bearbeiten
Hier ist ein speed-Vergleich mit der Java-built-in-Lösung vs 7zip.
Ich fügte hinzu, buffered input/output-streams in meiner ursprünglichen Lösung (danke Jim, dies machte einen großen Unterschied machen).
Zip Dateigröße: 800K
Java Lösung: 2.7 Sekunden
7Zip Lösung: 204 ms
Hier ist der geänderte code mit dem built-in Java-Dekompression:
/** Unpacks the give zip file using the built in Java facilities for unzip. */
@SuppressWarnings("unchecked")
public final static void unpack(File zipFile, File rootDir) throws IOException
{
ZipFile zip = new ZipFile(zipFile);
Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
while(entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
java.io.File f = new java.io.File(rootDir, entry.getName());
if (entry.isDirectory()) { //if its a directory, create it
continue;
}
if (!f.exists()) {
f.getParentFile().mkdirs();
f.createNewFile();
}
BufferedInputStream bis = new BufferedInputStream(zip.getInputStream(entry)); //get the input stream
BufferedOutputStream bos = new BufferedOutputStream(new java.io.FileOutputStream(f));
while (bis.available() > 0) { //write contents of 'is' to 'fos'
bos.write(bis.read());
}
bos.close();
bis.close();
}
}
- Ich habe keine Probleme mit der unzip-Funktionen, und ich habe die Verarbeitung von 250 MB zip-Dateien enthalten, die Gzip-komprimierter text-Dateien. Was machst du, dass das dauert so lange? Ist es etwas komplexer?
- Vielleicht, wenn Sie es tun, in einem low-priority-thread ?
- Ich empfehle:
if( entry.getName().contains("..") ) continue;
- Die Antwort auf diese Frage ist zwar sinnvoll, aber die Nützlichkeit hat keine Beziehung zu der Frage, (da die Frage an sich falsch war). Ich bin versucht zu gehen, ändern Sie die Frage zu "Warum ist mein entpacken von Java-code so langsam" zu helfen, zukünftige Suchende... Die top-Antwort ist ausgezeichnet, aber. Wäre es eine schlechte Idee, mich einfach gehen, und ändern Sie die Frage?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist nicht das entpacken, es ist die ineffiziente Art schreiben Sie die entpackten Daten wieder auf den Datenträger. Meine benchmarks zeigen, dass die Verwendung
reduziert stattdessen die Methode die Rechenzeit um einen Faktor 5 (von 5 auf 1 Sekunde für eine 6 MB zip-Datei).
Den wahrscheinlich Schuldigen ist Ihre Nutzung
bis.available()
. Abgesehen davon, dass falsche (zur Verfügung gibt die Anzahl der bytes, bis ein Aufruf von read blockieren würde, nicht bis das Ende des Streams), dadurch wird die Pufferung zur Verfügung gestellt von BufferedInputStream, die eine native Systemaufruf für jedes byte kopiert, in die Ausgabe-Datei.Beachten Sie, dass das einwickeln in ein BufferedStream ist nicht erforderlich, wenn Sie die bulk read-und write-Methoden wie ich oben, und dass der code zum schließen der Ressourcen ist nicht exception-sicher (wenn das Lesen oder schreiben aus irgendeinem Grund fehlschlägt, weder
is
nochos
geschlossen werden würde). Schließlich, wenn Sie haben IOUtils in die Klasse Pfad, empfehle ich, mit Ihren gut getestetIOUtils.copy
anstatt Ihre eigenen Rollen.Stellen Sie sicher, Sie füttern das unzip-Methode einen BufferedInputStream in Ihre Java-Anwendung. Wenn Sie den Fehler gemacht, mit einer ungepufferten Eingabe-stream Ihrer IO-Leistung ist garantiert zu saugen.
Fand ich eine 'unelegant' Lösung. Es ist ein open source-Dienstprogramm 7zip (www.7-zip.org), die kostenlos zu benutzen. Herunterladen können Sie die Kommandozeilen-version (http://www.7-zip.org/download.html). 7-zip ist nur auf Windows unterstützt, aber es sieht so aus, wurde eine Portierung auf andere Plattformen (p7zip).
Offensichtlich diese Lösung ist nicht ideal, da es Plattform-spezifische und stützt sich auf eine ausführbare Datei. Allerdings ist die Geschwindigkeit im Vergleich zu tun, das entpacken in Java ist unglaublich.
Hier ist der code für die utility-Funktion, die ich erstellt, um eine Schnittstelle mit diesem Dienstprogramm. Es gibt Raum für Verbesserungen, wie der code unten ist Windows-spezifisch.