如何在Java中创建Uncompressed Zip存档

20 java zip crc32

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

此外,当我使用该STORED方法时,它抛出以下异常:

java.util.zip.ZipException: STORED entry missing size, compressed size, or crc-32
Run Code Online (Sandbox Code Playgroud)

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

java.util.zip.ZipException: invalid entry crc-32 
Run Code Online (Sandbox Code Playgroud)

我只是通过在网上搜索来关注所有可用的示例,我猜我无法正确理解它.如果有人可以帮助我,并提供我纠正我可能正在做的问题的建议,那将是很棒的.

PMo*_*nCA 12

我对aperkins解决方案很感兴趣(自删除以来),但我知道它为何有效.这条线(后来在他的回答中得到纠正)

zipOut.setLevel(ZipOutputStream.STORED); // accidentally right
Run Code Online (Sandbox Code Playgroud)

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

zipOut.setMethod(ZipOutputStream.DEFLATED); // this line optional
zipOut.setLevel(0);
Run Code Online (Sandbox Code Playgroud)

要么

zipOut.setLevel(Deflater.NO_COMPRESSION);
Run Code Online (Sandbox Code Playgroud)

如果你使用

zipOut.setMethod(ZipOutputStream.STORED);
zipOut.setLevel(Deflater.NO_COMPRESSION);
Run Code Online (Sandbox Code Playgroud)

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

  • DEFLATED + Level(0)导致我的情况......每个压缩文件(一个位)比来源文件更大:O我很确定DEFLATED-0与STORE不同:/ (2认同)
  • DEFLATED-0和STORE _might_不同,但它们具有相同的目标 - 包含未压缩数据的zip文件.我不希望任何一种方法都会输出一个大小与源文件相同的文件.但是在这个问题中,Keya在使用STORE方法时遇到了麻烦,因为需要进行预处理才能获得所需的参数.如果您想要一个小于源文件的压缩文件,请在setLevel()中使用不同的值 - 但这不是问题所要求的. (2认同)

Chr*_*rle 7

您需要使用的STORED方法,但是这需要您设置的size,compressedSize并且crc32相应的属性ZipEntry后,才能调用putNextEntryZipOutputStream.您可以使用a预先计算CRC-32 Crc32OutputStream.

  • 它在 https://www.pkware.com/documents/casestudies/APPNOTE.TXT 的 ZIP 文件格式规范中指定。 (2认同)

Li *_*ing 5

供参考:

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

public void setLevel(int level) {
    def.setLevel(level);
}
Run Code Online (Sandbox Code Playgroud)

它只是将压缩级别设置重定向到字段变量[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;
Run Code Online (Sandbox Code Playgroud)

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

zipOut.setMethod(ZipOutputStream.DEFLATED);
zipOut.setLevel(Deflater.NO_COMPRESSION);
Run Code Online (Sandbox Code Playgroud)