簡體   English   中英

Apache 共享:UnsupportedZipFeatureException (LZMA)

[英]Apache Commons: UnsupportedZipFeatureException (LZMA)

我想解壓縮使用 Windows 10 的壓縮功能創建的.zip 文件(內部帶有 .jpg 文件)。

首先,我使用 Java 8 的本機util.zip.ZipEntry對其進行了測試,但一直收到invalid CEN header (bad compression method)

因此,我切換到 Apache Common 的Compress庫(版本 1.2)。 存檔中的前兩個圖像解壓縮正常,但第三個總是拋出異常:

org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException: 不支持的壓縮方法 14 (LZMA) 用於條目 image3.jpg

如何使用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();
}

我還使用示例站點上提供的“LZMA”代碼(其中還包括添加“xz”)甚至CompressorInputStream對其進行了測試,但無論我做什么,我都會不斷收到某種類型的異常,例如:

org.tukaani.xz.UnsupportedOptionsException:未壓縮的大小太大

幸運的是,有一個非官方的解決方案,作為這個問題答案發布。 說明:

您的代碼不起作用的原因是 Zip LZMA 壓縮數據段與普通壓縮 LZMA 文件相比具有不同的 header 。

使用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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM