Java NIO ZipFileSystem:创建文件系统时“找不到zip END标头”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37413379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:28:56  来源:igfitidea点击:

Java NIO ZipFileSystem: "zip END header not found" while creating file system

javazipniozipfile

提问by Ton van Bart

I'm asking this here because googling this error only gives me hits on writing a zip file, while I'm only trying to read it.
I have a unit test where I'm trying to test the following production code:

我在这里问这个是因为谷歌搜索这个错误只会给我写一个 zip 文件的命中率,而我只是试图阅读它。
我有一个单元测试,我正在尝试测试以下生产代码:

Map<String, String> zipProps = new HashMap<>();
URI zipUri = URI.create("jar:file:" + itemZipPath.toString());
try (FileSystem zipfiles = FileSystems.newFileSystem(zipUri, zipProps)) {
   // do stuff...
} catch (IOException e) {
   // log an error
}

However this fails on the line containing the try:

但是,这在包含 try 的行上失败:

java.util.zip.ZipError: zip END header not found
at com.sun.nio.zipfs.ZipFileSystem.zerror(ZipFileSystem.java:1605)
at com.sun.nio.zipfs.ZipFileSystem.findEND(ZipFileSystem.java:1021)
at com.sun.nio.zipfs.ZipFileSystem.initCEN(ZipFileSystem.java:1030)
at com.sun.nio.zipfs.ZipFileSystem.<init>(ZipFileSystem.java:130)
at com.sun.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:117)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:326)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:276)
at com.company.PageCommandHandler$ProvisioningSteps.getItemModel(PageCommandHandler.java:105)

I've tried creating the zipfile using both OSX's zip utility and using jar cvfbut both fail (the output of file <filename>differs slightly however). All the information about this error I can find relates to creating a zipfile using Java NIO, but as you can see I'm only doing a read (verifying the presence of a certain file inside the ZIP for now). Any thoughts on what is going wrong here?

我已经尝试使用 OSX 的 zip 实用程序创建 zipfile 并使用jar cvf但都失败(但是输出file <filename>略有不同)。我能找到的有关此错误的所有信息都与使用 Java NIO 创建 zipfile 相关,但正如您所看到的,我只是在执行读取操作(目前验证 ZIP 中是否存在某个文件)。关于这里出了什么问题的任何想法?

回答by Alexandr

I've met exactly the same error. Java 8. The reason was, by mistake I created an empty file, not only object:

我遇到了完全相同的错误。Java 8. 原因是,我错误地创建了一个空文件,而不仅仅是对象:

File zipFile = new File(path);
zipFile.createNewFile();

An then passed this path to

然后通过这条路径到

URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());

To fix it, I did not create file itself, only created a File object:

为了修复它,我没有创建文件本身,只创建了一个 File 对象:

File zipFile = new File(path);
URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());

To make it more reliable I would offer to delete file first if it exists:

为了使它更可靠,我会提议先删除文件(如果存在):

File zipFile = new File(path);
//Caused by: java.util.zip.ZipError: zip END header not found
if (zipFile.exists()){
    try {
        Files.delete(Paths.get(zipFile.getAbsolutePath()));
    } catch (IOException e) {
        throw new IllegalStateException(
                "Could not delete file.", e);
    }
}
...
URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());

Probably in some case the solution with deletion of the file is not acceptable. For instance, if you add to the same zip file several entries. But in my use case it is OK.

可能在某些情况下,删除文件的解决方案是不可接受的。例如,如果您向同一个 zip 文件添加多个条目。但在我的用例中是可以的。

回答by Ton van Bart

I tried using the normal ZipInputStream and related classes, but kept having issues, so the problem did not seem related to NIO. A colleague of mine found this question on SO: Extracting zipped file from ResourceStream throws error "Invalid stored block lengths"

我尝试使用普通的 ZipInputStream 和相关类,但一直有问题,所以问题似乎与 NIO 无关。我的一位同事在 SO 上发现了这个问题:从 ResourceStream 中提取压缩文件抛出错误“存储块长度无效”

So I tried adding this snippet to my pom.xml as well:

所以我也尝试将此代码段添加到我的 pom.xml 中:

<properties>
    <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
</properties>

After this, all problems disappeared and all my tests turned green. I did not revert back to NIO as I was happy enough getting to a working solution, but I'm pretty sure this would solve the problem on NIO as well.

在此之后,所有问题都消失了,我所有的测试都变成了绿色。我没有回到 NIO,因为我很高兴找到一个可行的解决方案,但我很确定这也能解决 NIO 上的问题。

Posted here in hopes that it helps somebody having the same issue some day.

发布在这里希望它可以帮助有一天遇到同样问题的人。

回答by Tech-IO

Maybe you didn't used the ZipInputStream class ? What is on line 326 ?

也许您没有使用 ZipInputStream 类?326 行是什么?

Here is some example for decompressing and extracting zip files. http://www.oracle.com/technetwork/articles/java/compress-1565076.html

下面是一些用于解压缩和提取 zip 文件的示例。 http://www.oracle.com/technetwork/articles/java/compress-1565076.html

FileInputStream fis = new FileInputStream("figs.zip"); ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis));

FileInputStream fis = new FileInputStream("figs.zip"); ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis));

Once a ZIP input stream is opened, you can read the zip entries using the getNextEntry method which returns a ZipEntry object. If the end-of-file is reached, getNextEntry returns null:

打开 ZIP 输入流后,您可以使用返回 ZipEntry 对象的 getNextEntry 方法读取 zip 条目。如果到达文件尾,getNextEntry 返回 null: