如何解压缩zip文件的特定目录中的所有文件?

时间:2015-04-06 20:04:17

标签: java zip extract unzip subdirectory

假设我有一个名为 Bundles.zip 的.zip文件,并且直接在 Bundles.zip 中,有几个文件和几个文件夹。这就是.zip的样子:

Bundles.zip top level screenshot

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

zip中的 Bundles 文件夹可以包含子文件夹中的文件,子文件夹,文件,基本上都是这样的:

Bundles.zip inner folder screenshot

我只需要从 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”。在拉链内有一个名为The Island的文件夹。我需要找到zip文件中与zip文件名称匹配的文件夹,并提取其中的所有内容。

2 个答案:

答案 0 :(得分:6)

更简单的方法是使用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文件。

答案 1 :(得分:0)

该文件的路径(文件夹)是&#34; zipEntry.getName()&#34;的一部分。返回,并且应该知道您需要的信息,只要知道文件是否在您寻找的文件夹中。

我会做类似的事情:

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

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

如果您需要将代码深入到子目录中,可以执行类似的操作。显然这不会编译,但你明白了。该方法调用自身,并返回自身,使得可以根据需要深入到子文件夹中。

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.
    }
  } 
}
相关问题