Apache Commons:UnsupportedZipFeatureException (LZMA)
Apache Commons: UnsupportedZipFeatureException (LZMA)
我想解压缩使用 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:
Unsupported compression method 14 (LZMA) used in entry 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();
}
我还使用 examples site (which also includes adding the "xz" library) 甚至 CompressorInputStream
上提供的“LZMA”代码对其进行了测试,但无论我做了什么,我都会不断收到某种类型的异常,例如:
org.tukaani.xz.UnsupportedOptionsException: Uncompressed size is too
big
幸运的是,有一个非官方的修复程序,发布为 answer for this question。解释:
The reason your code isn't working, is that Zip LZMA compressed data
segments have a different header compared to normal compressed LZMA
files.
使用 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();
}
我想解压缩使用 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: Unsupported compression method 14 (LZMA) used in entry 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();
}
我还使用 examples site (which also includes adding the "xz" library) 甚至 CompressorInputStream
上提供的“LZMA”代码对其进行了测试,但无论我做了什么,我都会不断收到某种类型的异常,例如:
org.tukaani.xz.UnsupportedOptionsException: Uncompressed size is too big
幸运的是,有一个非官方的修复程序,发布为 answer for this question。解释:
The reason your code isn't working, is that Zip LZMA compressed data segments have a different header compared to normal compressed LZMA files.
使用 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();
}