【发布时间】:2019-02-13 11:39:06
【问题描述】:
我的类路径 (Java 8) 上有一个有效的 zip 文件。它长 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 上观察到了这种行为。
【问题讨论】:
-
src不在 CLASSPATH 上。它在运行时根本不存在。您应该将 ZIP 作为资源而不是文件来访问。 -
它在类路径中,并且在运行时存在,并且正在被读取。这正是我想要做的,作为资源访问。
-
从表面上看,这种行为似乎是不可能的。您能否向我们提供一个 MCVE,我们可以用它来为自己复制它。
-
类路径资源是直接来自文件系统,还是你把你的类和资源打包成一个jar文件?在后一种情况下,问题可能在您创建 jar 文件时发生 - 该过程可能损坏了 zip 文件。尝试解压 jar 文件,然后查看 zip 文件是否损坏。
-
我过去曾在 try-with-resources 块中遇到过麻烦。你试过不使用它吗?获取try里面的资源,最后关闭流。
标签: java zip inputstream