如何解决 org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException

0

当解压缩 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)
如果觉得这对你有用,请随意赞赏,给与作者支持
回答 (1)
1 个回答

0

已采纳

发生这种情况是因为你有这个 mimetype 文件附加的 “数据描述符(data descriptor)”。默认情况下(和规范)只允许 DEFLATED 压缩算法的文件具有此功能,但是你的压缩文件使用的是 STORED(即 ZIP 中的文件没有使用压缩算法)。

只需使用 allowStoredEntriesWithDataDescriptor = true 构造您的 ZipArchiveInputStream 即可。

public ZipArchiveInputStream(InputStream inputStream,
                         String encoding,
                         boolean useUnicodeExtraFields,
                         boolean allowStoredEntriesWithDataDescriptor)

不幸的是,对于 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 介绍和使用案例代码分享》