简体   繁体   中英

How to decompress a zip archive which has sub directories?

Say I have a zip file MyZipFile.zip which contains (1) a file MyFile.txt and (2) a folder MyFolder which contains a file MyFileInMyFolder.txt , ie something as follows:

MyZipFile.zip
|-> MyFile.txt
|-> MyFolder
|-> MyFileInMyFolder.txt

I want to decompress this zip archive. The most common code sample I have been able to find searching online uses the ZipInputStream class somewhat like the code pasted at the bottom of this question. The problem with this however, using the example above, is that it will create MyFolder but will not decompress the contents of MyFolder . Anyone know whether it is possible to decompress the contents of a folder in a zip archive using ZipInputStream or by any other means?

public static boolean unzip(File sourceZipFile, File targetFolder)
{
 // pre-stuff

 ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(sourceZipFile));
 ZipEntry zipEntry = null;

 while ((zipEntry = zipInputStream.getNextEntry()) != null)
 {
  File zipEntryFile = new File(targetFolder, zipEntry.getName());

  if (zipEntry.isDirectory())
  {
   if (!zipEntryFile.exists() && !zipEntryFile.mkdirs())
    return false;
  }
  else
  {
   FileOutputStream fileOutputStream = new FileOutputStream(zipEntryFile);

   byte buffer[] = new byte[1024];
   int count;

   while ((count = zipInputStream.read(buffer, 0, buffer.length)) != -1)
    fileOutputStream.write(buffer, 0, count); 

   fileOutputStream.flush();
   fileOutputStream.close();
   zipInputStream.closeEntry();
  }
 }

 zipInputStream.close();

 // post-stuff
}

Try this:

ZipInputStream zis = null;
try {

    zis = new ZipInputStream(new FileInputStream(zipFilePath));
    ZipEntry entry;

    while ((entry = zis.getNextEntry()) != null) {

        // Create a file on HDD in the destinationPath directory
        // destinationPath is a "root" folder, where you want to extract your ZIP file
        File entryFile = new File(destinationPath, entry.getName());
        if (entry.isDirectory()) {

            if (entryFile.exists()) {
                logger.log(Level.WARNING, "Directory {0} already exists!", entryFile);
            } else {
                entryFile.mkdirs();
            }

        } else {

            // Make sure all folders exists (they should, but the safer, the better ;-))
            if (entryFile.getParentFile() != null && !entryFile.getParentFile().exists()) {
                entryFile.getParentFile().mkdirs();
            }

            // Create file on disk...
            if (!entryFile.exists()) {
                entryFile.createNewFile();
            }

            // and rewrite data from stream
            OutputStream os = null;
            try {
                os = new FileOutputStream(entryFile);
                IOUtils.copy(zis, os);
            } finally {
                IOUtils.closeQuietly(os);
            }
        }
    }
} finally {
    IOUtils.closeQuietly(zis);
}

Note, that it uses Apache Commons IO to handle stream copying / closing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM