2013-03-13 99 views
6

我想压缩目录内容到zip档案使用java。 一切都很好,但我只是想澄清一些事实。 下面是我用它来压缩文件中的代码:压缩的zip档案

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(); 
    } 
    } 
}

现在有问题:

  1. 它是正确的,在默认情况下(在我的情况也是如此),我会得到已经被压缩档案(使用Deflate方法)?

  2. 如何获得无压缩归档:

    • 如果我设置方法zipOutputStream.setMethod(ZipOutputStream.STORED)我必须提供大小,压缩后的大小(是这将是等于大小?)和CRC,否则我会得到异常
    • 如果我不想自己计算大小和crc,我可以使用DEFLATE零级别的方法:
      zipOutputStream.setMethod(ZipOutputStream.DEFLATED); 
      zipOutputStream.setLevel(ZipOutputStream.STORED);
      因此,在这种情况下,我是否没有压缩存档?
    • 是否有更方便明显的创建未压缩存档的方法?
+3

This [answer](http://stackoverflow.com/a/1207041/354831)可能会帮助你STORED。 – 2013-03-13 08:21:04

+1

根据您的使用情况,您也可以考虑'.tar'格式,而不是'.zip',用于未压缩的归档。其中一个lib:https://code.google.com/p/jtar/ – hyde 2013-03-13 08:45:05

回答

-2

而不是重新发明轮子我会认真考虑使用现有的库本,如Apache Ant的。创建zip文件的基本习惯用法是:

Project p = new Project(); 
p.init(); 
Zip zip = new Zip(); 
zip.setProject(p); 
zip.setDestFile(new File(outputDir, "out.zip")); 
FileSet fs = new FileSet(); 
fs.setProject(p); 
fs.setDirectory(targetDir); 
zip.addFileset(fs); 
zip.perform(); 

默认情况下,您将获得压缩存档。对于未压缩的压缩,所有你需要补充的是

zip.setCompress(false); 
setDestFile

(其实perform之前的任何地方)。