26

我正在使用 Java 的 Zip 实用程序包,想知道如何创建一个完全不压缩的 zip 文件。将级别设置为 0 无济于事。这是正确的吗?

另外,当我使用该STORED方法时,它会引发以下异常:

java.util.zip.ZipException: STORED entry missing size, compressed size, or crc-32

我可以设置大小,但现在抛出以下异常:

java.util.zip.ZipException: invalid entry crc-32 

我只是通过在网上搜索所有可用的示例,我想我无法真正理解它。如果有人可以在这方面帮助我并为我提供纠正我可能正在做的问题的建议,那就太好了。

4

3 回答 3

20

我对aperkins解决方案持怀疑态度(已删除),但我知道它为什么有效。该行(此后已在他的回答中更正)

zipOut.setLevel(ZipOutputStream.STORED); // accidentally right

正在使用静态值ZipOutputStream.STORED,巧合地等于0。因此,该行所做的是将默认 DEFLATED 方法使用的级别设置为零压缩(这显然是您想要做的,但碰巧只能靠运气工作)。因此,要明确安全地获得您想要的东西,请改用它:

zipOut.setMethod(ZipOutputStream.DEFLATED); // this line optional
zipOut.setLevel(0);

或者

zipOut.setLevel(Deflater.NO_COMPRESSION);

如果你使用

zipOut.setMethod(ZipOutputStream.STORED);
zipOut.setLevel(Deflater.NO_COMPRESSION);

您可能会得到 Keya 在原始问题中指出的异常。我相信Christian Schlichtherle是对的。您收到异常是因为您没有在条目中设置 CRC。这样做的后果是,要使用 STORED 方法,您必须先读取整个入口文件,或者在调用之前找到其他方法来设置大小、压缩大小(必须相等)和 CRCzipOut.putNextEntry(). 否则,如果您通过向输出流写入过多字节来超出 size 属性,您将遇到更多异常。似乎 ZIP 规范说,如果您正在编写 STORED 数据,那么它必须在数据本身之前“预先”写入标头 [包括 CRC-32 和长度],因此 java API 需要在它之前设置这些可以启动,因为它基本上只支持流式传输到最终的 zip 文件。

于 2012-11-30T22:23:33.493 回答
8

你需要使用该STORED方法,但这需要你设置好对应的,sizecompressedSize属性crc32ZipEntry才能调用putNextEntry. ZipOutputStream您可以使用Crc32OutputStream.

于 2011-05-03T10:56:28.573 回答
6

供参考:

在方法 [java.util.zip.ZipOutputStream.setLevel(int)] 的 JDK 源中:

public void setLevel(int level) {
    def.setLevel(level);
}

它只是将压缩级别设置重定向到字段变量 [def],它是 [java.util.zip.Deflater] 的一个实例。

而在类[java.util.zip.Deflater]的源代码中:

/**
 * Compression level for no compression.
 */
public static final int NO_COMPRESSION = 0;

/**
 * Compression level for fastest compression.
 */
public static final int BEST_SPEED = 1;

/**
 * Compression level for best compression.
 */
public static final int BEST_COMPRESSION = 9;

/**
 * Default compression level.
 */
public static final int DEFAULT_COMPRESSION = -1;

所以,我认为如果你使用常量值 [Deflater.NO_COMPRESSION] 会更易读:

zipOut.setMethod(ZipOutputStream.DEFLATED);
zipOut.setLevel(Deflater.NO_COMPRESSION);
于 2014-10-23T02:48:41.223 回答