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

发布于 2024-10-12 16:21:40 字数 77 浏览 3 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

乖乖 2024-10-19 16:21:40

这是我的。

在文件中指定要扩展的文件
在目标目录中,您必须将目标位置指定为“new File(”/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);
}

为我工作。祝你好运。

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.

就此别过 2024-10-19 16:21:40

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

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

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;
      }
 }
南街女流氓 2024-10-19 16:21:40

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

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

您需要将文件解压到同一目录中。解析然后这样命名:

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

}

或多或少应该可以做到这一点(您仍然需要处理重复的文件名等)

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)

眼波传意 2024-10-19 16:21:40
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();
}
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();
}
欢你一世 2024-10-19 16:21:40

为什么你关心秩序?

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文