I have a simple code to extract zip files, it was working just fine as expected but during my test I tried my code with some zip files (fonts, icons and templates I downloaded from internet) just to make sure it should extract any zip files provided, but its not working with some zip files, here is the minimized code to regenerate this issue:
package com.test.mytest;
import java.io.FileInputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class ZipExtractTest {
public static final String ZIP_FILE = "/Users/XXXXX/Downloads/janne.zip";
public static void main(String[]args) {
unzipFile(ZIP_FILE);
unzipStream(ZIP_FILE);
}
public static void unzipFile(String zipName) {
try {
ZipFile zf = new ZipFile(zipName);
Enumeration ent = zf.entries();
while(ent.hasMoreElements()) {
System.out.println(ent.nextElement());
}
} catch(Exception e) {
System.out.println(e);
}
}
public static void unzipStream(String zipName) {
try {
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipName));
ZipEntry ze = zis.getNextEntry();
if(ze == null) {
System.out.println("unable to get first entry from zip file");
zis.close();
return;
}
while(ze != null) {
System.out.println("Entry Found: " + ze);
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
} catch(Exception e) {
System.out.println(e);
}
}
}
actually In my real application i have to extract zip files through inputstreams. In the code above I am trying to extract "janne.zip" I downloaded this file from http://www.iconian.com/fonts/janne.zip I am able to extract it using any zip-tool and surprisingly through "unzipFile(String zipName)" method as well, but with unzipStream(String zipName) method
ZipEntry ze = zis.getNextEntry();
returns null
any help would be appreciated
Not an answer as to why this particular file doesn't work with java.util.zip
, but if you have the option to replace your use of java.util.zip.ZipInputStream
with the Apache commons-compress org.apache.commons.compress.archivers.zip.ZipArchiveInputStream
(which should be API-compatible) then I've just tested that on your example file and it seems to work successfully.
Generally I find commons-compress to be much more reliable than java.util.zip
at unpacking files created by tools other than the java.util.zip
classes themselves.
Edit: I've done a bit of debugging in Eclipse and it looks like this particular zip file has a single segment spanning marker of 0x30304b50
before the LOC signature (0x04034b50
) of the first entry's local header. This is something that commons-compress knows how to handle but java.util.zip
doesn't - if j.u.z.ZipInputStream
sees anything other than a LOC signature then getNextEntry()
will return null
.