如何解决 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 介绍和使用案例代码分享》。