2013-03-13 7 views
6

Ich versuche, Verzeichnisinhalt in Zip-Archiv mit Java zu komprimieren. Alles ist in Ordnung, aber ich möchte nur einige Fakten klären. Hier ist der Code, den ich verwende, um Dateien zu komprimieren:Komprimierung von Zip-Archiv

public void pack(@Nonnull String archiveName, @Nonnull File outputDir, @Nonnull File targetDir) { 
    File zipFile = new File(outputDir, "out.zip"); 

    ZipOutputStream zipOutputStream = null; 
    OutputStream outputStream; 
    try { 
    // create stream for writing zip archive 
    outputStream = new FileOutputStream(zipFile); 
    zipOutputStream = new ZipOutputStream(outputStream); 
    // write files recursively 
    writeFiles(zipOutputStream, targetDir.listFiles(), ""); 
    } catch (IOException e) { 
    LOGGER.error("IO exception while packing files to archive", e); 
    } finally { 
    // close output streams 
    if (zipOutputStream != null) { 
     try { 
     zipOutputStream.close(); 
     } catch (IOException e) { 
     LOGGER.error("Unable to close zip output stream", e); 
     } 
    } 
    } 
} 

/** 
* Writes specified files and their children (in case of directories) to archive 
* 
* @param zipOutputStream archive output stream 
* @param files   which should be added to archive 
* @param path   path relative of root of archive where files should be placed 
*/ 
private void writeFiles(@Nonnull ZipOutputStream zipOutputStream, @Nullable File[] files, @Nonnull String path) throws IOException { 
    if (files == null || files.length == 0) { 
    return; 
    } 

    for (File file : files) { 
    if (file.isDirectory()) { 
     // recursively add files in this directory 
     String fullDirectoryName = path + file.getName() + "/"; 
     File[] childFiles = file.listFiles(); 
     if (childFiles != null && childFiles.length > 0) { 
     // write child files to archive. current directory will be created automatically 
     writeFiles(zipOutputStream, childFiles, fullDirectoryName); 
     } else { 
     // empty directory. write directory itself to archive 
     ZipEntry entry = new ZipEntry(fullDirectoryName); 
     zipOutputStream.putNextEntry(entry); 
     zipOutputStream.closeEntry(); 
     } 
    } else { 
     // put file in archive 
     BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); 
     zipOutputStream.putNextEntry(new ZipEntry(path + file.getName())); 
     ByteStreams.copy(bufferedInputStream, zipOutputStream); 
     zipOutputStream.closeEntry(); 
     bufferedInputStream.close(); 
    } 
    } 
}

Nun gibt es die Fragen:

  1. Ist es richtig, dass standardmäßig (und in meinem Fall auch) Ich werde bereits komprimiert bekommen archivieren (mit der Deflate-Methode)?

  2. Wie unkomprimiertes Archiv erhalten:

    • Wenn ich Methode gesetzt zipOutputStream.setMethod(ZipOutputStream.STORED) Ich habe Größe zur Verfügung zu stellen, komprimierte Größe (es ist von der Größe gleich sein?) Und crc, sonst werde ich Ausnahmen erhalten
    • Wenn ich Größe und CRC nicht selbst berechnen möchte, kann ich DEFLATE Methode mit Null-Ebene verwenden:
      zipOutputStream.setMethod(ZipOutputStream.DEFLATED); 
      zipOutputStream.setLevel(ZipOutputStream.STORED);
      Also, ist es richtig, dass ich in diesem Fall nicht komprimierte Archiv überhaupt bekomme?
    • Gibt es eine praktischere Methode zum Erstellen nicht komprimierter Archive?
+3

Diese [Antwort] (http://stackoverflow.com/a/1207041/354831) kann Ihnen für die gespeicherten helfen. –

+1

Sie können auch '.tar' anstelle von' .zip' für unkomprimiertes Archiv verwenden, abhängig von Ihrem Anwendungsfall. Eine Lib dafür: https://code.google.com/p/jtar/ – hyde

Antwort

-2

Anstatt neu erfinden das Rad ich ernsthaft in Erwägung ziehen würde eine vorhandene Bibliothek für diese, wie Apache Ant verwenden. Das grundlegende Idiom zum Erstellen einer Zip-Datei ist:

Standardmäßig erhalten Sie ein komprimiertes Archiv. Für eine nicht komprimierte Zip-alles, was Sie brauchen, ist

zip.setCompress(false); 

nach dem setDestFile (in der Tat überall vor dem perform).