我在我的类路径上有一个有效的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上的任何地方