如何在Java中recursion解压缩文件?

我有zip文件,其中包含一些其他的zip文件。 例如,邮件文件是abc.zip,它包含xyz.zip,class1.java,class2.java。 而xyz.zip包含文件class3.java和class4.java。

所以我需要提取使用java的zip文件到一个文件夹,该文件夹应该包含class1.java,class2.java,class3.java和class4.java。

这个解决scheme与已经发布的解决scheme非常相似,但是这个解压方法重新创build了正确的文件夹结构。

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()); } } } 

这里有一些未经testing的代码基于一些旧的代码,我有解压缩的文件。

 public void doUnzip(String inputZip, String destinationDirectory) throws IOException { int BUFFER = 2048; List zipFiles = new ArrayList(); File sourceZipFile = new File(inputZip); File unzipDestinationDirectory = new File(destinationDirectory); unzipDestinationDirectory.mkdir(); ZipFile zipFile; // Open Zip file for reading zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ); // Create an enumeration of the entries in the zip file Enumeration zipFileEntries = zipFile.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(unzipDestinationDirectory, currentEntry); destFile = new File(unzipDestinationDirectory, destFile.getName()); if (currentEntry.endsWith(".zip")) { zipFiles.add(destFile.getAbsolutePath()); } // grab file's parent directory structure File destinationParent = destFile.getParentFile(); // create the parent directory structure if needed destinationParent.mkdirs(); try { // extract file if not a directory if (!entry.isDirectory()) { BufferedInputStream is = new BufferedInputStream(zipFile.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(); } } catch (IOException ioe) { ioe.printStackTrace(); } } zipFile.close(); for (Iterator iter = zipFiles.iterator(); iter.hasNext();) { String zipName = (String)iter.next(); doUnzip( zipName, destinationDirectory + File.separatorChar + zipName.substring(0,zipName.lastIndexOf(".zip")) ); } } 

我采取ca.anderson4并删除列表zipFiles和重写一点点,这就是我得到:

 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(); } } } 

我testing过,它的工作原理

在testing中,我注意到File.mkDirs()不能在Windows下工作…

/ ** *对于给定的完整path名重新创build所有父目录** /

  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(); } } 

解压后应该closureszip文件。

 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); try { ...code from other answers ( ex. NeilMonday )... } finally { zip.close(); } } 

根据需要修改,然后混合一些最好的答案。 这个版本将会:

  • recursion提取一个zip到给定的位置

  • 创build空目录

  • 正确closures邮编


 public static void unZipAll(File source, File destination) throws IOException { System.out.println("Unzipping - " + source.getName()); int BUFFER = 2048; ZipFile zip = new ZipFile(source); try{ destination.getParentFile().mkdirs(); 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(destination, 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 = null; FileOutputStream fos = null; BufferedOutputStream dest = null; try{ is = new BufferedInputStream(zip.getInputStream(entry)); int currentByte; // establish buffer for writing file byte data[] = new byte[BUFFER]; // write the current file to disk fos = new FileOutputStream(destFile); 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); } } catch (Exception e){ System.out.println("unable to extract entry:" + entry.getName()); throw e; } finally{ if (dest != null){ dest.close(); } if (fos != null){ fos.close(); } if (is != null){ is.close(); } } }else{ //Create directory destFile.mkdirs(); } if (currentEntry.endsWith(".zip")) { // found a zip file, try to extract unZipAll(destFile, destinationParent); if(!destFile.delete()){ System.out.println("Could not delete zip"); } } } } catch(Exception e){ e.printStackTrace(); System.out.println("Failed to successfully unzip:" + source.getName()); } finally { zip.close(); } System.out.println("Done Unzipping:" + source.getName()); } 

和NeilMonday的答案一样,但提取空目录:

 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()); } } } 
 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 }