unzip a zipfile in the same hierachy using java.util.ZipFile

隐身守侯 提交于 2019-12-07 23:00:00

问题


given a zip file with multiple nested directory structure, how do I unzip it into the same tree structure? does ZipFile.entries() provide the enumeration in any order?


回答1:


Zip doesn't offer directory structure per se. The tree alike structure is built by having full path of each entry. ZipFile enumerates the entries in the same way they have been added to the file.

Note: java.util.ZipEntry.isDirectory() just tests if the last character of the name is '/', that's how it works.

What you need to extract the files into the same directory. Parse then name like that:

for(ZipEntry zipEntry : java.util.Collections.list(zipFile.entries())){//lazislav
    String name = zipEntry.getName();
    int idx = name.lastIndexOf('/');
    if (idx>=0) name=name.substring(idx)
    if (name.length()==0) continue;

    File f = new File(targetDir, name);

}

That shall do it more or less (you still need to take care of duplicate file names, etc)




回答2:


This is mine.

In file you specify the file you want to expand in target dir you have to specify the target location as "new File("/tmp/foo/bar")". If you want to extract in the current directory you can specify targetDir = new File(".")

public static void unzip(File file, File targetDir) throws ZipException,
        IOException {
    targetDir.mkdirs();
    ZipFile zipFile = new ZipFile(file);
    try {
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            File targetFile = new File(targetDir, entry.getName());
            if (entry.isDirectory()) {
                targetFile.mkdirs();
            } else {
                InputStream input = zipFile.getInputStream(entry);
                try {
                    OutputStream output = new FileOutputStream(targetFile);
                    try {
                        copy(input, output);
                    } finally {
                        output.close();
                    }
                } finally {
                    input.close();
                }
            }
        }
    } finally {
        zipFile.close();
    }
}

private static void copy(InputStream input, OutputStream output) 
        throws IOException {
    byte[] buffer = new byte[4096];
    int size;
    while ((size = input.read(buffer)) != -1)
        output.write(buffer, 0, size);
}

Worked for me. Good luck.




回答3:


Here's the one I use all the times. It should directly work after a copy/paste and in any circumstances.

     public static File unzip(File inFile, File outFolder)
 {  final int BUFFER = 2048;
      try
      {
           BufferedOutputStream out = null;
           ZipInputStream  in = new ZipInputStream(
                                         new BufferedInputStream(
                                              new FileInputStream(inFile)));
           ZipEntry entry;
           while((entry = in.getNextEntry()) != null)
           {
                //System.out.println("Extracting: " + entry);
                int count;
                byte data[] = new byte[BUFFER];

                //We will try to reconstruct the entry directories
                File entrySupposedPath = new File(outFolder.getAbsolutePath()+File.separator+entry.getName());

                //Does the parent folder exist?
                if (!entrySupposedPath.getParentFile().exists()){
                    entrySupposedPath.getParentFile().mkdirs();
                }


                // write the files to the disk
                out = new BufferedOutputStream(
                          new FileOutputStream(outFolder.getPath() + "/" + entry.getName()),BUFFER);

                while ((count = in.read(data,0,BUFFER)) != -1)
                {
                     out.write(data,0,count);
                }
                out.flush();
                out.close();
           }
           in.close();
           return outFolder;
      }
      catch(Exception e)
      {
           e.printStackTrace();
           return inFile;
      }
 }



回答4:


ZipFile zipFile = new ZipFile("archive.zip");
try {
  for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements();) {
    ZipEntry entry = entries.nextElement();

    if (entry.isDirectory()) {
      new File(entry.getName()).mkdirs();
    } else {
      InputStream in = zipFile.getInputStream(entry);
      try {
        OutputStream out = new BufferedOutputStream(new FileOutputStream(entry.getName()));
          try {
            // this util class is taken from apache commons io (see http://commons.apache.org/io/)
            IOUtils.copy(in, out);
          } finally {
            out.close();
          }
      } finally {
        in.close();
      }
    }
  }
} catch (IOException e) {
  e.printStackTrace();
} finally {
  zipFile.close();
}



回答5:


Why do you care about order?

If the ZipFile entry has a name /a/b/c/file.txt, then you can work out the directory name /a/b/c and then create a directory in your tree called a/b/c.



来源:https://stackoverflow.com/questions/4722049/unzip-a-zipfile-in-the-same-hierachy-using-java-util-zipfile

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!