为什么会抛出java.util.zip.ZipError
,是否可以抓住它?
javadoc说它意味着发生了不可恢复的错误 - 但这样的错误是什么?我听说它可能来自糟糕的zip文件。
编辑:
查看java.util.zip源代码显示,当尝试访问文件中不存在的元素时会抛出它,但java.util.zip.ZipFile
类的内部计数表明该元素应该存在。如果另一个线程在为此检查ensureOpen
方法后尝试关闭文件,或者java.util.zip.ZipFile
调用的本机方法出错,则会发生这种情况。如果在Java应用程序打开文件时更改了文件,就会发生这种情况。我并不真正理解所涉及的代码库的完整性(它很大!)。
答案 0 :(得分:3)
JDK问题JDK-4615343似乎促使Java 6中创建ZipError
。A comment on the issue为ZipError
的存在提供了一些启示:
该zip文件实现现在不再抛出InternalError了, 抛出java.util.zip.ZipError。
新异常引起争议,并扩展了InternalError。在 一般而言,不建议使用此方法,但需要 兼容性。现有程序可能已解决此问题 通过捕获InternalError。这样的程序将继续有效,但是我们 建议更新所有客户端以捕获java.util.zip.ZipError 代替。
这表明ZipError
是一个已知的不良设计,仅出于向后兼容的原因而存在。
看看Java 8源代码,同样可以确认ZipError
仅由ZipFile
迭代方法entries()和stream()抛出。
通过查看Java 9源代码,可以发现Java 9更进一步,并且不再抛出ZipError
。
关于为什么会抛出该错误,查看OpenJDK 8中的TestZipError.java源代码可知,可以在Windows上抛出这种情况。如果创建了ZipError
对象,则会引发ZipFile
,然后删除文件系统中的zip文件并使用其他条目创建它,然后迭代ZipFile
的内容。< / p>
这些事实提供了有力的证据,表明与大多数Error
不同的是–实际上,捕获抛出的ZipError
是合理的,并且将其视为正常的非Error
异常是合理的。尽管如果仅在Java 9+上运行代码,则可能根本不想打扰检查,因为在不可能的情况下这将是多余的代码。
答案 1 :(得分:2)
ZipError
表示一个低级别的JVM错误,尽管你可能像任何其他异常一样捕获它,但整个JVM有可能处于这样一种状态,即它不应该继续跑步。请注意,对于更常规的错误类型,有一个单独的ZipException
,例如损坏的文件,I / O错误等。