How to unzip files recursively in Java?

后端 未结 9 2005
慢半拍i
慢半拍i 2020-11-27 03:10

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

相关标签:
9条回答
  • 2020-11-27 03:22

    In testing I noticed File.mkDirs() does not work under Windows...

    /** * for a given full path name recreate all parent directories **/

        private void createParentHierarchy(String parentName) throws IOException {
            File parent = new File(parentName);
            String[] parentsStrArr = parent.getAbsolutePath().split(File.separator == "/" ? "/" : "\\\\");
    
            //create the parents of the parent
            for(int i=0; i < parentsStrArr.length; i++){
                StringBuffer currParentPath = new StringBuffer();
                for(int j = 0; j < i; j++){
                    currParentPath.append(parentsStrArr[j]+File.separator);
                }
                File currParent = new File(currParentPath.toString());
                if(!currParent.isDirectory()){
                    boolean created = currParent.mkdir();
                    if(isVerbose)log("creating directory "+currParent.getAbsolutePath());
                }
            }
    
            //create the parent itself
            if(!parent.isDirectory()){
                boolean success = parent.mkdir();
            }
        }
    
    0 讨论(0)
  • 2020-11-27 03:25
    File dir = new File("BASE DIRECTORY PATH");
    FileFilter ff = new FileFilter() {
    
        @Override
        public boolean accept(File f) {
            //only want zip files
            return (f.isFile() && f.getName().toLowerCase().endsWith(".zip"));
        }
    };
    
    File[] list = null;
    while ((list = dir.listFiles(ff)).length > 0) {
        File file1 = list[0];
        //TODO unzip the file to the base directory
    }
    
    0 讨论(0)
  • 2020-11-27 03:27

    Here is some code, which I tested to be working quite well :

    package com.test;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.Enumeration;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    
    public class Unzipper {  
        private final static int BUFFER_SIZE = 2048;
        private final static String ZIP_FILE = "/home/anton/test/test.zip";
        private final static String DESTINATION_DIRECTORY = "/home/anton/test/";
        private final static String ZIP_EXTENSION = ".zip";
     
        public static void main(String[] args) {
         System.out.println("Trying to unzip file " + ZIP_FILE); 
            Unzipper unzip = new Unzipper();  
            if (unzip.unzipToFile(ZIP_FILE, DESTINATION_DIRECTORY)) {
             System.out.println("Succefully unzipped to the directory " 
                 + DESTINATION_DIRECTORY);
            } else {
             System.out.println("There was some error during extracting archive to the directory " 
                 + DESTINATION_DIRECTORY);
            }
        } 
    
     public boolean unzipToFile(String srcZipFileName,
       String destDirectoryName) {
      try {
       BufferedInputStream bufIS = null;
       // create the destination directory structure (if needed)
       File destDirectory = new File(destDirectoryName);
       destDirectory.mkdirs();
    
       // open archive for reading
       File file = new File(srcZipFileName);
       ZipFile zipFile = new ZipFile(file, ZipFile.OPEN_READ);
    
       //for every zip archive entry do
       Enumeration<? extends ZipEntry> zipFileEntries = zipFile.entries();
       while (zipFileEntries.hasMoreElements()) {
        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
        System.out.println("\tExtracting entry: " + entry);
    
        //create destination file
        File destFile = new File(destDirectory, entry.getName());
    
        //create parent directories if needed
        File parentDestFile = destFile.getParentFile();    
        parentDestFile.mkdirs();    
        
        if (!entry.isDirectory()) {
         bufIS = new BufferedInputStream(
           zipFile.getInputStream(entry));
         int currentByte;
    
         // buffer for writing file
         byte data[] = new byte[BUFFER_SIZE];
    
         // write the current file to disk
         FileOutputStream fOS = new FileOutputStream(destFile);
         BufferedOutputStream bufOS = new BufferedOutputStream(fOS, BUFFER_SIZE);
    
         while ((currentByte = bufIS.read(data, 0, BUFFER_SIZE)) != -1) {
          bufOS.write(data, 0, currentByte);
         }
    
         // close BufferedOutputStream
         bufOS.flush();
         bufOS.close();
    
         // recursively unzip files
         if (entry.getName().toLowerCase().endsWith(ZIP_EXTENSION)) {
          String zipFilePath = destDirectory.getPath() + File.separatorChar + entry.getName();
    
          unzipToFile(zipFilePath, zipFilePath.substring(0, 
                  zipFilePath.length() - ZIP_EXTENSION.length()));
         }
        }
       }
       bufIS.close();
       return true;
      } catch (Exception e) {
       e.printStackTrace();
       return false;
      }
     } 
    }  
    

    I tried with the top voted answer here, and that does not recursively unzip the files, it just unzips the files of the first level.

    Source : Solution which extracts files into a given directory

    Also, check this solution by the same person : Solution which extracts file in memory

    0 讨论(0)
  • 2020-11-27 03:30

    I take ca.anderson4 and remove the List zipFiles and rewrite a little bit, this is what i got:

    public class Unzip {
    
    public void unzip(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
                unzip(destFile.getAbsolutePath());
            }
        }
    }
    
    public static void main(String[] args) {
        Unzip unzipper=new Unzip();
        try {
            unzipper.unzip("test/test.zip");
        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    }
    

    I tested and it works

    0 讨论(0)
  • 2020-11-27 03:35

    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());
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 03:37

    Same as NeilMonday's answer, but extracts empty directories:

    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();
            }
            else{
                destFile.mkdirs()
            }
            if (currentEntry.endsWith(".zip"))
            {
                // found a zip file, try to open
                extractFolder(destFile.getAbsolutePath());
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题