【问题标题】:java - How to unzip all the files in a specific directory of a zip file?java - 如何解压缩zip文件的特定目录中的所有文件?
【发布时间】:2015-06-11 07:01:49
【问题描述】:

假设我有一个名为 Bundles.zip 的 .zip 文件,直接在 Bundles.zip 内,有一些文件和一些文件夹。这是 .zip 的样子:

现在,我想从 Bundles 文件夹中提取 EVERYTHING。我的程序已经知道需要从中提取文件的文件夹的名称,在本例中为 Bundles

zip 中的 Bundles 文件夹可以有文件、子文件夹、子文件夹中的文件,基本上任何东西,像这样:

我只需要将 Bundles 文件夹中的所有内容提取到输出目录即可。

我如何在 Java 中实现这一点?我找到了提取 zip 中所有文件和文件夹的答案,但我只需要提取 zip 中的特定文件夹,而不是所有内容。

到目前为止的工作代码:

            ZipFile zipFile = new ZipFile(mapsDirectory + "mapUpload.tmp");
            Enumeration zipEntries = zipFile.entries();
            String fname;
            String folderToExtract = "";
            String originalFileNameNoExtension = originalFileName.replace(".zip", "");

            while (zipEntries.hasMoreElements()) {
                ZipEntry ze = ((ZipEntry)zipEntries.nextElement());

                fname = ze.getName();

                if (ze.isDirectory()) //if it is a folder
                {

                    if(originalFileNameNoExtension.contains(fname)) //if this is the folder that I am searching for
                    {
                        folderToExtract = fname; //the name of the folder to extract all the files from is now fname
                        break;
                    }
                }
            }

            if(folderToExtract == "")
            {
                printError(out, "Badly packaged Unturned map error:  " + e.getMessage());
                return;
            }


            //now, how do i extract everything from the folder named folderToExtract?

对于到目前为止的代码,originalFileName 类似于“The Island.zip”。在 zip 中有一个名为 The Island 的文件夹。我需要在 zip 文件中找到与 zip 文件名称匹配的文件夹,然后提取其中的所有内容。

【问题讨论】:

  • 您的工作代码在哪里? java zip 库允许您很好地遍历 zip 文件的内容
  • @kolossus - 到目前为止添加了我的工作代码以查找要提取的文件夹的名称。现在的问题是,如何提取名为 folderToExtract 的文件夹?

标签: java zip extract unzip subdirectory


【解决方案1】:

一种更简单的方法是使用 Java 7 的 NIO API。我刚刚为我的一个项目做到了这一点:

private void extractSubDir(URI zipFileUri, Path targetDir)
        throws IOException {

    FileSystem zipFs = FileSystems.newFileSystem(zipFileUri, new HashMap<>());
    Path pathInZip = zipFs.getPath("path", "inside", "zip");
    Files.walkFileTree(pathInZip, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) throws IOException {
            // Make sure that we conserve the hierachy of files and folders inside the zip
            Path relativePathInZip = pathInZip.relativize(filePath);
            Path targetPath = targetDir.resolve(relativePathInZip.toString());
            Files.createDirectories(targetPath.getParent());

            // And extract the file
            Files.copy(filePath, targetPath);

            return FileVisitResult.CONTINUE;
        }
    });
}

瞧。比使用 ZipFileZipEntry 干净得多,而且它还有一个额外的好处,即可以重复用于从任何类型的文件系统复制文件夹结构,而不仅仅是 zip 文件。

【讨论】:

  • 完美运行!不要忘记使用“/”作为 zipFs.getPath() API 的第一个参数。
【解决方案2】:

文件的路径(文件夹)是“zipEntry.getName()”返回的一部分,并且应该为您提供所需的信息,以了解文件是否在您寻找的文件夹中。

我会这样做:

while (zipEntries.hasMoreElements()) {
  //fname should have the full path
  if (ze.getName().startsWith(fname) && !ze.isDirectory())
    //it is a file within the dir, and it isn't a dir itself
    ...extract files...
  }
}

ZipFile 有一个 getInputStream 方法来获取给定 ZipEntry 的输入流,所以,类似这样:

InputStream instream = zipFile.getInputStream(ze);

然后从流中读取字节并将它们写入文件。

如果您需要您的代码深入到子目录的 1 层以上,您可以执行以下操作。显然这不会编译,但你明白了。该方法调用自身,然后返回自身,从而可以尽可能深入地进入子文件夹。

private void extractFiles(String folder) {
  //get the files for a given folder
  files = codeThatGetsFilesAndDirs(folder);

  for(file in files) {
    if(file.isDirectory()) {
      extractFiles(file.getName()); 
    } else {
      //code to extract the file and writes it to disk.
    }
  } 
}

【讨论】:

  • 这适用于获取 zip 文件夹中的文件,但我如何处理文件夹中的子目录?我要从中提取文件的 zip 文件夹中也有子目录,这些子目录中也有文件。
  • 您可以编写一个往复式方法,该方法将遍历自身,以便它可以遍历目录树……这有点拗口。我将发布一个简单的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 2020-11-30
相关资源
最近更新 更多