如何解决 org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException
当解压缩 zip 文件时,我的 jboss 显示错误。
错误消息:
14:36:20,663 ERROR [STDERR] org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException: unsupported feature data descriptor used in entry mimetype
14:36:20,663 ERROR [STDERR] at org.apache.commons.compress.archivers.zip.ZipArchiveInputStream.read(ZipArchiveInputStream.java:245)
14:36:20,663 ERROR [STDERR] at java.io.InputStream.read(Unknown Source)
这里的 test.epub 压缩文件内部文件详情:
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
20 Stored 20 0% 03-18-2013 14:39 2cab616f mimetype
0 Stored 0 0% 03-18-2013 10:42 00000000 META-INF/
265 Defl:N 187 29% 03-18-2013 10:42 4d7842ce META-INF/container.xml
1048 Defl:N 271 74% 03-18-2013 10:42 c04d123d META-INF/encryption.xml
0 Stored 0 0% 03-18-2013 12:05 00000000 OEBPS/
1014 Defl:N 530 48% 03-18-2013 12:05 cb8218d1 OEBPS/9.html
使用的是 commons-compress-1.4.jar, 1.5 版本也同样显示这个错误。
有人知道为什么发生错误,我如何解决?
这是源代码:
public void unzip(InputStream is, File destDir, String charsetName)
throws IOException {
ZipArchiveInputStream zis;
ZipArchiveEntry entry;
String name;
File target;
int nWritten = 0;
BufferedOutputStream bos;
byte[] buf = new byte[1024 * 8];
zis = new ZipArchiveInputStream(is, charsetName, false);
while ((entry = zis.getNextZipEntry()) != null) {
name = entry.getName();
target = new File(destDir, name);
if (entry.isDirectory()) {
target.mkdirs();
} else {
Util.createParentDirectory(target);
target.createNewFile();
bos = new BufferedOutputStream(new FileOutputStream(target));
while ((nWritten = zis.read(buf)) >= 0) {
bos.write(buf, 0, nWritten);
}
bos.close();
debug("file : " + name);
}
}
zis.close();
}
当我使用其他 LIB(java.util.zip),还示出了下面的异常。
java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor
at java.util.zip.ZipInputStream.readLOC(Unknown Source)
at java.util.zip.ZipInputStream.getNextEntry(Unknown Source)
已采纳
发生这种情况是因为你有这个
mimetype
文件附加的 “数据描述符(data descriptor
)”。默认情况下(和规范)只允许DEFLATED
压缩算法的文件具有此功能,但是你的压缩文件使用的是STORED
(即 ZIP 中的文件没有使用压缩算法)。只需使用
allowStoredEntriesWithDataDescriptor = true
构造您的ZipArchiveInputStream
即可。不幸的是,对于
java.util.zip
来说这似乎不可行:https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/zip/ZipInputStream.java Java的#L310 行。这个问题的根本原因是压缩文件不符合标准规范,使用
STORED
模式存储的 zip 文件内部文件是不经过压缩的,并且不允许添加额外的描述信息,如果有的话 jdk 会直接抛出异常,不再处理。另外可以使用
zip4j
库来操作这类不规范的 zip 文件,请参考 《zip4j 介绍和使用案例代码分享》。