使用java.util.ZipFile解压缩同一层次结构中的zip文件

时间:2011-01-18 08:46:21

标签: java unzip

给定一个具有多个嵌套目录结构的zip文件,如何将其解压缩到同一个树结构中? ZipFile.entries()以任何顺序提供枚举吗?

5 个答案:

答案 0 :(得分:3)

这是我的。

在文件中指定要扩展的文件 在目标目录中,您必须将目标位置指定为"新文件(" / tmp / foo / bar")"。如果要在当前目录中提取,可以指定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);
}

为我工作。祝你好运。

答案 1 :(得分:2)

这是我一直使用的那个。它应该在复制/粘贴之后以及在任何情况下直接工作。

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

Zip本身不提供目录结构。树类结构是通过每个条目的完整路径构建的。 ZipFile以与添加到文件相同的方式枚举条目。

注意:java.util.ZipEntry.isDirectory()只是测试名称的最后一个字符是否为'/',这就是它的工作原理。

将文件解压缩到同一目录中需要什么。然后Parse那样命名:

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

}

这应该或多或少(你仍然需要处理重复的文件名等)

答案 4 :(得分:0)

你为什么关心订单?

如果ZipFile条目的名称为/a/b/c/file.txt,那么您可以计算出目录名/a/b/c,然后在树中创建一个名为a/b/c的目录。