java - ZipInputStream.getNextEntry 在某些 zip 文件上返回 null

标签 java unzip zip compression

我有一个简单的代码来提取 zip 文件,它按预期工作得很好,但在我的测试中,我用一些 zip 文件(我从互联网下载的字体、图标和模板)尝试了我的代码,只是为了确保它应该提取提供的任何 zip 文件,但它不适用于某些 zip 文件,这里是重新生成此问题的最小化代码:

package com.test.mytest;

import java.io.FileInputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

public class ZipExtractTest {

    public static final String ZIP_FILE = "/Users/XXXXX/Downloads/janne.zip";

    public static void main(String[]args) {
        unzipFile(ZIP_FILE);
        unzipStream(ZIP_FILE);
    }

    public static void unzipFile(String zipName) {
        try {

            ZipFile zf = new ZipFile(zipName);

            Enumeration ent = zf.entries();

            while(ent.hasMoreElements()) {
                System.out.println(ent.nextElement());
            }

        } catch(Exception e) {
            System.out.println(e);
        }
    }

    public static void unzipStream(String zipName) {
        try {
            ZipInputStream zis = new ZipInputStream(new FileInputStream(zipName));
            ZipEntry ze = zis.getNextEntry();

            if(ze == null) {
                System.out.println("unable to get first entry from zip file");
                zis.close();
                return;
            }

            while(ze != null) {
                System.out.println("Entry Found: " + ze);
                ze = zis.getNextEntry();
            }

            zis.closeEntry();
            zis.close();

        } catch(Exception e) {
            System.out.println(e);
        }
    }
}

实际上,在我的实际应用程序中,我必须通过输入流提取 zip 文件。在上面的代码中,我试图提取“janne.zip”,我从 http://www.iconian.com/fonts/janne.zip 下载了这个文件。我能够使用任何 zip 工具提取它,令人惊讶的是,我也可以通过“unzipFile(String zipName)”方法提取它,但是使用 unzipStream(String zipName) 方法

ZipEntry ze = zis.getNextEntry();

返回空值

任何帮助将不胜感激

最佳答案

没有回答为什么这个特定文件不能与 java.util.zip 一起工作,但如果您可以选择替换 java.util.zip 的使用。 ZipInputStreamApache commons-compress org.apache.commons.compress.archivers.zip.ZipArchiveInputStream(应该是 API 兼容的)然后我刚刚在您的示例文件上测试了它,它似乎可以成功运行。

通常我发现 commons-compress 在解压缩由 java.util.zip 类本身以外的工具创建的文件时比 java.util.zip 可靠得多.

编辑:我在 Eclipse 中做了一些调试,看起来这个特定的 zip 文件有一个 single segment spanning marker。在第一个条目的本地 header 的 LOC 签名 (0x04034b50) 之前的 0x30304b50。这是 commons-compress knows how to handle 的东西但 java.util.zip 没有 - 如果 j.u.z.ZipInputStream 看到除 LOC 签名之外的任何内容,则 getNextEntry() 将返回

关于java - ZipInputStream.getNextEntry 在某些 zip 文件上返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15521966/

相关文章:

java - hibernate 不加载关联对象

java - java中如何删除字符串中的所有特殊字符?

linux - 如何在linux和windows下实现相同的压缩

ubuntu - 如何在 Linux 中提取 zip 文件并保留原始文件?

java - 在 JVM7 中卡住,但在 JVM6 中不卡住

java - 如何让 Gson 使用Externalables?

matlab - 在不提取Matlab中的内容的情况下读取Zip文件中的CSV文件的数据

linux - 为什么我收到 IO::Uncompress::Unzip::unzip: input filename is undef or null string 消息?

python - 将不同行的 csv 写入保持相同标题的列中? - Python

python - 如何通过 Python 2.7 将字节附加到 zip 文件内的文件中?