我的类路径上有一个有效的zip文件(Java 8)。它长302617字节。我想使用标准的ApacheCommons IO Utils将其复制到临时文件夹,以便在我的应用程序中进行扩展和进一步处理。如果我把它作为文件阅读,例如:
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。
但是,如果我从类路径输入流中读取:
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个和第12个字节(10111010 10011110,hex ba 9e)从类路径输入流中读取为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文件可以在类路径的任何位置