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

Ton*_*art 6 java zip nio zipfile

我在这里问这个是因为谷歌搜索这个错误只会给我写一个 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
}
Run Code Online (Sandbox Code Playgroud)

但是,这在包含 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)
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*ndr 5

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

File zipFile = new File(path);
zipFile.createNewFile();
Run Code Online (Sandbox Code Playgroud)

然后通过这条路径到

URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());
Run Code Online (Sandbox Code Playgroud)

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

File zipFile = new File(path);
URI uri = URI.create("jar:file:" + zipFile.getAbsolutePath());
Run Code Online (Sandbox Code Playgroud)

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

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());
Run Code Online (Sandbox Code Playgroud)

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


Ton*_*art 3

我尝试使用普通的 ZipInputStream 和相关类,但仍然遇到问题,因此问题似乎与 NIO 无关。我的一位同事在 SO 上发现了这个问题:Extracting zipped file from ResourceStream throws error "Invalid storage block lengths"

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

<properties>
    <project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
</properties>
Run Code Online (Sandbox Code Playgroud)

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

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