Java ZipInputStream 抛出 zip.ZipException : invalid distance too far back while parsing nested zip files

标签 java zip zipinputstream

首先我要承认,我已经阅读了此处和互联网上的多个主题,但我的问题仍然存在,而且似乎有些不同。

我有一个 zip 文件,其中包含多个 .txt 文件、目录、该目录的子目录等。里面还有大量的 zip 存档,里面有 zip、目录和文件。最深层次的归档是 5 个步骤 -> 5 个 zip,一个在另一个里面,其中包含不同的文件。

我有这个代码:

ZipFile zipFile = new ZipFile(Objects.requireNonNull(this.classLoader.getResource("inputs.zip")).getFile());
    Enumeration<? extends ZipEntry> entries = zipFile.entries();
    while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        InputStream stream = zipFile.getInputStream(entry);
        System.out.println(entry.getName());
        processZipFile(stream);
    }

这是 processZipFile:

private void processZipFile(InputStream stream) throws IOException {
    ZipInputStream zipInputStream = new ZipInputStream(stream);
    ZipEntry zipEntry = zipInputStream.getNextEntry();
    while (zipEntry != null) {
        System.out.print("    /" + zipEntry.getName());
        if (zipEntry.getName().endsWith(".zip")) {
            processZipFile(stream);
        }
        zipEntry = zipInputStream.getNextEntry();
    }

直到归档级别 3 为止,一切似乎都工作正常,列出了所有目录、zip、gzip 和子目录,但当处理像 input.zip/1.zip/2.zip 这样的内容时,它会抛出异常

Exception in thread "main" java.util.zip.ZipException: invalid distance too far back

正如我在 Java 8 文档中读到的ZipInputStream.getNextEntry(): 读取下一个 ZIP 文件条目并将流定位在条目数据的开头。因为在获取条目后程序会抛出异常。

在这种情况下,“2.zip”内的文件相当大 - 800 MB,与最大大小为 3 MB 的其他情况相比 - 我想知道它是否会影响程序。

我试图在不解压这些 zipper 的情况下完成所有这些事情,这在这里非常重要。我知道这种错误通常与损坏的 zip 文件有关,但这些错误是完全合法的。

所以我的问题是 - 我如何浏览所有这些嵌套的 zip 文件?

编辑/解决方案:

根据 Talex 提出的更改,我已修复了代码以在 ZipInputStreams 而不是标准 InputStreams 上工作。它不再抛出错误,但不知怎的,它仍然跳过比 3 级归档更深的嵌套 zip(仍然不确定这是否是正确的命名方法,哈哈)。解决方案也很简单 - 当我将 ZipInputStream 循环传递给我的函数时,我将它包装到另一个 ZipInputStream 中。代码如下:

private void processZipFile(ZipInputStream zipInputStream) throws IOException {
    ZipEntry zipEntry;
    while ((zipEntry = zipInputStream.getNextEntry()) != null) {
        System.out.println("    " + zipEntry.getName());
        if (zipEntry.getName().endsWith(".zip")) {
            processZipFile(new ZipInputStream(zipInputStream));
        } else if (zipEntry.getName().endsWith(".txt")) {
           //other things to todo...
        }
        //other things to todo...
    }

最佳答案

而不是

processZipFile(stream);

你需要使用

processZipFile(zipInputStream);

关于Java ZipInputStream 抛出 zip.ZipException : invalid distance too far back while parsing nested zip files,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58604687/

相关文章:

Java:获取带有接口(interface)参数的方法及其实现

在滑动窗口中查找字符串匹配的算法

c# - 用于 .Net C# 应用程序的 SharpZipLib 替代品

android - 使用 ZipInputStream 错误 UTFDataFormatException 提取文件

java - 有没有办法使用分段上传(Java 高级 API)使用 "java.util.zip"将提取的 zip 文件上传到 AWS-S3

java - 从列表中获取任何元素

java - 在 Java 中将球图像放到我的球对象上时遇到问题

java - 有关 github 上此幻灯片菜单库的更多信息

.NET 4.5 ZipFile 类未生成一致的文件

Java - Zip 输出流动态缓冲区大小