java - 压缩 zip 存档

标签 java zip deflate

<分区>

我正在尝试使用 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);
      那么,在这种情况下我根本没有得到压缩存档是否正确?
    • 是否有更方便、更明显的方法来创建未压缩的存档?

最佳答案

与其重新发明轮子,我会认真考虑为此使用现有的库,例如 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,您需要添加的是

zip.setCompress(false);

setDestFile 之后(实际上是在 perform 之前的任何地方)。

关于java - 压缩 zip 存档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15379925/

相关文章:

json - JSON 或文本文件的最佳 zip 压缩级别?

java - 如何在网页中运行java .class 文件?

java - Google App Engine 中的 JDO : order of keys in unowned one-to-many relationship

Unix 压缩子目录不包括父目录

iphone - iOS/Objective-C读取4GB或更高的压缩存档库?

java - 放气机 : is it possible to clone state (or rollback)?

android - 如何在 Android 中压缩字符串

Java Elasticsearch 数据库测试

java - Android Studio Electric Eel - 提供的 javaHome 似乎无效。尝试位置 : C:\Program Files\Android\Android Studio\jre\bin\java. exe

python - 无法使用 SSZipArchive 在 iOS9 中解压缩大型 zip 文件 (3.3GB)