【问题标题】:zip4j produces zip with all files' size = 0zip4j 生成所有文件大小 = 0 的 zip
【发布时间】:2018-03-29 20:13:42
【问题描述】:

我在通过zip4j 生成 ZIP 文件时遇到问题。

我可以使用以下代码生成 ZIP 存档(我省略了一些与问题无关的部分),基本上取自 zip4j 教程:

File zipFile = new File(zipName);
ZipParameters params = new ZipParameters();
params.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
params.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
byte[] buffer = new byte[8192];
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile))) {
   for (/* loop through list of input data */) {
        String outputName = /* method to determine file name */;
        try (InputStream in = /* method to get IS */ ) {
            params.setFileNameInZip(outputName);
            File tmpEntry = new File(outputName);
            tmpEntry.createNewFile();
            out.putNextEntry(tmpEntry, params);
            int len;
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            tmpEntry.delete();
            out.closeEntry();
            in.close();
        }
    }
}

问题在于,虽然所有文件都正确包含在 ZIP 存档中,但它们声明的文件大小为 0。我可以使用“哑”ZIP 阅读器(如内置 TotalCommander 的阅读器)解压缩它们,因为所有数据实际上都在这里,但更“聪明”的程序(如 7zip)会产生 CRC 错误并拒绝打开它们,因为它们已损坏。

我会说我需要以某种方式声明文件大小(我绝对不会在我的代码 sn-p 中这样做),但我无法找到(可能很明显)解决方案。我用谷歌搜索了原生java.util.zip.ZipEntry.setSize() 方法,但我在zip4j 中没有看到类似的东西...

有人知道正确的方法吗?

【问题讨论】:

  • 在循环内为每个 putNextEntry 创建一个新的 ZipParameters。顺便说一句,删除 in.close();
  • 我尝试了您的建议,但输出仍然相同 - 所有文件显示大小 = 0
  • 我不知道 zip4j 但仍然是一个建议:在tmpEntry.delete() 之前调用out.closeEntry()。后者可能是零尺寸的罪魁祸首。
  • 感谢您的想法。不幸的是,这也没有完成这项工作:(

标签: java zip zip4j


【解决方案1】:

所以解决方案非常简单。只需将以下设置添加到ZipParameters

params.setSourceExternalStream(true);

我是怎么发现的?

我深入研究了代码并在CipherOutputStream.javazip4j 类的closeEntry() 方法中找到了以下内容:

if (zipParameters.isSourceExternalStream()) {
    fileHeader.setUncompressedSize(totalBytesRead);
    if (localFileHeader.getUncompressedSize() != totalBytesRead) {
        localFileHeader.setUncompressedSize(totalBytesRead);
    }
}

这是唯一调用 setUncompressedSize() 的地方 - 这听起来像是与声明的文件大小有关 - 方法被调用。所以我开始怀疑并试图在我的代码中设置参数。它可以完成这项工作。

吸取的教训是,this example 使用 zip4j 是不正确的,因为它缺少那一行重要的代码。

【讨论】:

    猜你喜欢
    • 2014-10-13
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多