apachecommons:unsupportedzipfeatureexception(lzma)

oipij1gg  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(513)

我想解压缩使用Windows10的压缩功能创建的.zip文件(其中包含.jpg文件)。
首先我用java8的本机测试了它 util.zip.ZipEntry 但一直都有问题 invalid CEN header (bad compression method) 错误,这似乎是由于与win10的压缩不兼容引起的。
正因为如此,我换上了apache common的 Compress 库(版本1.2)。归档文件中的前两个图像可以解压缩,但第三个图像总是引发异常:
org.apache.commons.compress.archivers.zip.unsupportedzipfeatureexception:条目image3.jpg中使用了不受支持的压缩方法14(lzma)
如何使用 Compress 图书馆?这有可能吗?
我的代码:

ZipFile z = new ZipFile(zippath);
Enumeration<ZipArchiveEntry> entries = z.getEntries();

while(entries.hasMoreElements()) {
    ZipArchiveEntry entry = entries.nextElement();
    System.out.println("Entry: "+entry.getName());
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipfolder+"\\"+entry.getName()));
    BufferedInputStream bis = new BufferedInputStream(z.getInputStream(entry));
    byte[] buffer=new byte[1000000];
    int len=0;

    while((len=bis.read(buffer,0,1000000))>0) {
        bos.write(buffer, 0, len)  ;
    }
    bis.close();
    bos.close();
}
fnvucqvd

fnvucqvd1#

我还使用examples站点上提供的“lzma”代码(其中还包括添加“xz”库)甚至 CompressorInputStream 但不管我做了什么,我总是得到一些例外,例如:
org.tukaani.xz.unsupportedoptionsexception:未压缩的大小太大
幸运的是,有一个非官方的修复,作为这个问题的答案张贴。解释如下:
代码无法工作的原因是zip lzma压缩的数据段与普通压缩的lzma文件具有不同的头。
使用 getInputstreamForEntry (这是在回答中发布的),我的代码现在能够处理zip存档中的lzma和非lzma文件:

ZipFile z = new ZipFile(zipfile);
Enumeration<ZipArchiveEntry> entries = z.getEntries();

while(entries.hasMoreElements()) {
    ZipArchiveEntry entry = entries.nextElement();
    System.out.println("Entry: "+entry.getName());
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipfolder+"\\"+entry.getName()));
    BufferedInputStream bis = null;

    try {
        bis  = new BufferedInputStream(z.getInputStream(entry));
    } catch(UnsupportedZipFeatureException e) {
        bis  = new BufferedInputStream(getInputstreamForEntry(z, entry));
    }

    byte[] buffer=new byte[1000000];
    int len=0;

    while((len=bis.read(buffer,0,1000000))>0) {
        bos.write(buffer, 0, len)  ;
    }
    bis.close();
    bos.close();
}

相关问题