为啥我在使用 java.util.zip.ZipFile 打开空 ZIP 文件时出现异常?

Posted

技术标签:

【中文标题】为啥我在使用 java.util.zip.ZipFile 打开空 ZIP 文件时出现异常?【英文标题】:Why I get an Exception on opening an empty ZIP-file with java.util.zip.ZipFile?为什么我在使用 java.util.zip.ZipFile 打开空 ZIP 文件时出现异常? 【发布时间】:2008-12-12 15:09:43 【问题描述】:

我想打开一个 ZIP 文件,它没有包含 java.util.zip.ZipFile 的条目。但是在构造函数上,我得到以下异常:'java.util.zip.ZipException:打开 zip 文件时出错'。如何打开空的 ZIP?

该 ZIP 文件是由 linux 下的命令行 zip 程序创建的。我只是从一个 ZIP 文件中删除了所有条目。

我需要这个作为我编写的课程的测试数据。对于这种情况,该类应该只返回一个空列表,但损坏的 ZIP 文件应该返回一个错误。

有关该问题的更多解释。我有一个接口,用于从不同来源提取一些文档。其他实现从 web 服务或目录中收集它们,这个实现来自 ZIP 文件。该接口为 Iterator 提供了更多功能。所以我想决定 ZIP 文件是空的还是损坏的。

【问题讨论】:

它是空的(但仍然是带有标题等的格式良好的 ZIP 文件)还是零字节文件? 它的大小为 22 字节。我通过删除所有条目使用命令行-zip 创建了它。 【参考方案1】:

hack:您可以假设所有空 ZIP 都是相同的,只需对其长度/校验和进行硬编码以进行验证。

【讨论】:

这确实是一个 hack,但它确实可以工作。至少值得一票,谢谢。 :-)【参考方案2】:

不知道为什么要这样实现,但是为什么需要成功打开一个空的Zip文件呢?无论如何,您都无法使用 java.util.zip.ZipFile 对其进行修改...

因此,您可以捕获 ZipException(对于无效格式的 zip 文件会抛出该异常),并在捕获时跳过该文件。

【讨论】:

在我以前不知道的用例中,该文件将为空。在这种情况下,我编写的类也应该可以正常工作。 我应该如何判断它是一个空的 ZIP 文件还是损坏的 ZIP 文件?而且我没有 ZipFile 对象可以使用。 您确定需要知道它是坏的还是空的?在这两种情况下,它对您的程序都是无用的。因此,对于无用的文件,您基本上不需要任何对象。如果我错了,那么您应该说明您的目标,也许我们可以找到更好的解决方案。【参考方案3】:

我现在对这个问题的解决方案是,我只是使用 ZipInputStream 而不是 ZipFile。此类适用于空 ZIP 文件。我不知道原因,为什么一个有效而另一个无效。

【讨论】:

【参考方案4】:

我认为 ZipInputStream 有效而 ZipFile 无效的原因是因为读取 zip 文件的两种不同方式。 ZipFile 构造函数尝试读取 ZipFile 的目录,该目录被写入文件末尾。如果它无法读取 TOC,它会抛出一个 ZipException(其中几乎不包含任何有用的信息),我认为这就是您所看到的。然而,ZipInputStream 从文件的开头开始按顺序从 zip 文件中读取条目,因此在这种情况下它看起来更健壮。

这一切都记录得很差,我自己在使用 ZipFile 时也遇到过类似的问题。从 zip 文件读取的两种方法都是有效的,但您可能认为 API 文档会提到通过构造函数读取随机访问/TOC 方法与通过 ZipInputStream 读取的含义。

【讨论】:

【参考方案5】:

您确定这是一个有效的 zip 文件吗?这是我的第一个猜测。

【讨论】:

【参考方案6】:

ZIP 文件格式有错误check the JDK here。

【讨论】:

空拉链不是错误,而是空拉链。无法区分空 zip 和以 zip 格式打开的图像文件。【参考方案7】:

使用ZipOutputStream

【讨论】:

以上是关于为啥我在使用 java.util.zip.ZipFile 打开空 ZIP 文件时出现异常?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 foreach 时会收到 ***Error?

为啥我在使用任务时无法正确填充集合? [复制]

为啥我在使用 Jetpack Compose TextField 时会出错?

当我在模型中使用 withAnimation 时,没有动画发生,为啥?

为啥我在使用 WideCharToMultiByte 时得到错误的字符数组?

即使我在 laravel 中使用 updateorcreate 方法,为啥还要复制数据