Java ZipInputStream 抛出 zip.ZipException:解析嵌套 zip 文件时无效距离太远
Java ZipInputStream throws zip.ZipException: invalid distance too far back while parsing nested zip files
首先我要承认,我已经阅读了这里和互联网上的几个话题,我的问题仍然存在,而且似乎有所不同。
我有一个 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 和子目录,但是当涉及到处理输入之类的东西时。zip/1。[=45= .zip 它抛出异常
Exception in thread "main" java.util.zip.ZipException: invalid distance too far back
正如我在 Java 8 个文档 ZipInputStream.getNextEntry()
中所读:
Reads the next ZIP file entry and positions the stream at the beginning of the entry data.
因为刚拿到入口程序就抛出异常。
在这种情况下,“2.zip”中的文件相当大 - 800 MB 与其他最大大小为 3 MB 的情况相比 - 我想知道它是否会影响程序。
我正在尝试在不打开这些 zips 的情况下完成所有这些事情,这在这里非常重要。我知道这种错误通常与损坏的 zip 文件有关,但这些错误是完全合法的。
所以我的问题是 - 如何浏览所有这些嵌套的 zip 文件?
EDIT/SOLUTION:
根据 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);
首先我要承认,我已经阅读了这里和互联网上的几个话题,我的问题仍然存在,而且似乎有所不同。
我有一个 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 和子目录,但是当涉及到处理输入之类的东西时。zip/1。[=45= .zip 它抛出异常
Exception in thread "main" java.util.zip.ZipException: invalid distance too far back
正如我在 Java 8 个文档 ZipInputStream.getNextEntry()
中所读:
Reads the next ZIP file entry and positions the stream at the beginning of the entry data.
因为刚拿到入口程序就抛出异常。
在这种情况下,“2.zip”中的文件相当大 - 800 MB 与其他最大大小为 3 MB 的情况相比 - 我想知道它是否会影响程序。
我正在尝试在不打开这些 zips 的情况下完成所有这些事情,这在这里非常重要。我知道这种错误通常与损坏的 zip 文件有关,但这些错误是完全合法的。
所以我的问题是 - 如何浏览所有这些嵌套的 zip 文件?
EDIT/SOLUTION:
根据 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);