0

我想解压缩使用 Windows 10 的压缩功能创建的 .zip 文件(其中包含 .jpg 文件)。

首先我用Java 8的本机测试了它,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();
}
4

1 回答 1

0

我还使用示例站点上提供的“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();
}
于 2020-12-17T13:57:25.433 回答