I want to unzip .zip files (with .jpg files inside) that were created using Windows 10’s zipping feature.
First I tested it with Java 8’s native util.zip.ZipEntry
but kept getting an invalid CEN header (bad compression method)
error, which seems to be caused by an incompatibility with Win10’s compression.
Because of that I switched to Apache Common’s Compress
library (version 1.2). The first two images in the archive unzip fine but the third always throws an exception:
org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException: Unsupported compression method 14 (LZMA) used in entry image3.jpg
How do I fully unzip this archive with the Compress
library? Is that even possible?
My code:
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(); }
Advertisement
Answer
I also tested it with the “LZMA” code provided on the examples site (which also includes adding the “xz” library) and even a CompressorInputStream
but no matter what I did, I kept getting some type of exception, e.g.:
org.tukaani.xz.UnsupportedOptionsException: Uncompressed size is too big
Fortunately there’s an inofficial fix for that, posted as an answer for this question. The explanation:
The reason your code isn’t working, is that Zip LZMA compressed data segments have a different header compared to normal compressed LZMA files.
Using getInputstreamForEntry
(which was posted in the answer), my code is now able to deal with both LZMA and non-LZMA files in a zip archive:
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(); }