How to unzip files recursively in Java?

Anish picture Anish · Jun 11, 2009 · Viewed 59.9k times · Source

I have zip file which contains some other zip files.

For example, the mail file is abc.zip and it contains xyz.zip, class1.java, class2.java. And xyz.zip contains the file class3.java and class4.java.

So I need to extract the zip file using Java to a folder that should contain class1.java, class2.java, class3.java and class4.java.

Answer

NeilMonday picture NeilMonday · Aug 18, 2011

Warning, the code here is ok for trusted zip files, there's no path validation before write which may lead to security vulnerability as described in zip-slip-vulnerability if you use it to deflate an uploaded zip file from unknown client.


This solution is very similar to the previous solutions already posted, but this one recreates the proper folder structure on unzip.

static public void extractFolder(String zipFile) throws ZipException, IOException 
{
    System.out.println(zipFile);
    int BUFFER = 2048;
    File file = new File(zipFile);

    ZipFile zip = new ZipFile(file);
    String newPath = zipFile.substring(0, zipFile.length() - 4);

    new File(newPath).mkdir();
    Enumeration zipFileEntries = zip.entries();

    // Process each entry
    while (zipFileEntries.hasMoreElements())
    {
        // grab a zip file entry
        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
        String currentEntry = entry.getName();
        File destFile = new File(newPath, currentEntry);
        //destFile = new File(newPath, destFile.getName());
        File destinationParent = destFile.getParentFile();

        // create the parent directory structure if needed
        destinationParent.mkdirs();

        if (!entry.isDirectory())
        {
            BufferedInputStream is = new BufferedInputStream(zip
            .getInputStream(entry));
            int currentByte;
            // establish buffer for writing file
            byte data[] = new byte[BUFFER];

            // write the current file to disk
            FileOutputStream fos = new FileOutputStream(destFile);
            BufferedOutputStream dest = new BufferedOutputStream(fos,
            BUFFER);

            // read and write until last byte is encountered
            while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
                dest.write(data, 0, currentByte);
            }
            dest.flush();
            dest.close();
            is.close();
        }

        if (currentEntry.endsWith(".zip"))
        {
            // found a zip file, try to open
            extractFolder(destFile.getAbsolutePath());
        }
    }
}