【问题标题】:Java NIO ZipFileSystem: "zip END header not found" while creating file systemJava NIO ZipFileSystem:创建文件系统时“找不到zip END标头”
【发布时间】:2023-03-19 21:46:01
【问题描述】:

我在这里问这个问题是因为谷歌搜索这个错误只会让我在编写 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
}

但是这在包含 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)

我尝试使用 OSX 的 zip 实用程序和 jar cvf 创建 zip 文件,但都失败了(file &lt;filename&gt; 的输出略有不同)。 我能找到的有关此错误的所有信息都与使用 Java NIO 创建 zipfile 相关,但正如您所见,我只是在进行读取(现在验证 ZIP 中是否存在某个文件)。 对这里出了什么问题有任何想法吗?

【问题讨论】:

    标签: java zip nio zipfile


    【解决方案1】:

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

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

    然后将这条路径传递给

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

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

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

    为了让它更可靠,如果文件存在,我会先删除它:

    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());
    

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

    【讨论】:

      【解决方案2】:

      我尝试使用普通的 ZipInputStream 和相关类,但一直有问题,所以问题似乎与 NIO 无关。 我的一位同事在 SO 上发现了这个问题:Extracting zipped file from ResourceStream throws error "Invalid stored block lengths"

      所以我也尝试将这个 sn-p 添加到我的 pom.xml 中:

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

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

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

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

        • 也许我没有把问题说得足够清楚——我不想用ZipInputStream;我正在尝试使用 Java 7 NIO ZipFileSystem。这只需要一个路径或 URI 并将其视为一个单独的文件系统。文件系统的创建应通过工厂方法:FileSystems.newFileSystem(zipUri, zipProps)),此 API 中不涉及 zip 输入流。我会尝试更新问题以使其更清楚。
        • @TonvanBart 对不起,那是 NIO 是的。让我们尽快等待答案。
        猜你喜欢
        • 1970-01-01
        • 2021-09-20
        • 1970-01-01
        • 2019-02-23
        • 2017-10-19
        • 1970-01-01
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多