为什么从java中的class路径上的zip文件中读取输入流



我在我的类路径上有一个有效的zip文件(Java 8)。它是302617字节长。 我想使用标准的ApacheCommons IO UTITS将其复制到临时文件夹中以进行扩展和进一步处理。 如果我将其读为文件,例如:

    File out = new File("out.zip");
    File in = new File ("src/main/resources/StartUpData/c4.zip");
    try (InputStream is = new FileInputStream(in);
               FileOutputStream fos = new FileOutputStream(out)   ) {
          IOUtils.copy(is, fos);
          System.out.println(out.length());
    }

这完全按预期工作 - 打印302617。

但是,如果我从classpath输入流中读取:

 try (InputStream is2 = this.getClass().getResourceAsStream("/StartUpData/c4.zip");         
        FileOutputStream fos = new  FileOutputStream(out)) {
        IOUtils.copy(is2, fos);
        System.out.println(out.length());
    }

它生成一个544115字节的文件。它不是有效的ZIP格式,无法通过任何命令行zip utils或Java解开拉链或读取为zip文件。我只使用zip文件观察这种行为;对于其他二进制文件或图像,两种方法都可以正常工作。

我研究了两种情况下正在阅读的字节。这是文件的第一个12个字节,来自 xxd -b c4.zip

00000000: 01010000 01001011 00000011 00000100 00010100 00000000    PK....
00000006: 00001000 00001000 00001000 00000000 10111010 10011110  ......

文件中的第11个字节(1011101010011110,十六进制BA 9E)从classPath输入流读取为Hex ef bf。

实际上,任何将第一个位设置为1的字节都被

创建的输入流误读

this.getClass().getResourceAsStream("/StartUpData/c4.zip")

有人知道为什么仅对从类路径读取zip文件发生这种情况?如何将10111010 10011110解释为EF BF?非常感谢您的建议。我正在使用MacOS High Sierra,我的同事还观察到Windows 10的这种行为。

这是一个Maven过滤问题,请参见https://maven.apache.org/plugins/maven-resources-plugin/examples/binaries-filtering.html。添加ZIP作为排除修复了此操作,并且zip文件可以在classPath上的任何地方

最新更新