简体   繁体   English

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

[英]java - How to unzip all the files in a specific directory of a zip file?

Say I have a .zip file called Bundles.zip and directly inside Bundles.zip , there are a few files and a few folders. 假设我有一个名为Bundles.zip的.zip文件,并且直接在Bundles.zip中 ,有几个文件和几个文件夹。 This is what the .zip looks like: 这就是.zip的样子:

Bundles.zip顶级截图

Now, I want to extract EVERYTHING from the Bundles folder. 现在,我想提取从捆绑文件夹中的一切 My program already knows the name of the folder that it needs to extract the files from, in this case, Bundles . 我的程序已经知道从中提取文件所需的文件夹的名称,在本例中为Bundles

The Bundles folder inside the zip can have files, subfolders, files in the subfolders, basically anything, like this: zip中的Bundles文件夹可以包含子文件夹中的文件,子文件夹,文件,基本上都是这样的:

Bundles.zip内部文件夹截图

And I just need to extract everything from the Bundles folder to an output directory. 我只需要从Bundles文件夹中提取所有内容到输出目录。

How can I accomplish this in Java? 我怎样才能在Java中实现这一目标? I have found answers which extract all the files and folders inside the zip, but I need to extract only a specific folder inside the zip, not everything. 我找到了提取zip中所有文件和文件夹的答案,但我只需要提取zip中的特定文件夹,而不是一切。

Working code so far: 到目前为止工作代码:

            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?

For the code so far, the originalFileName is something like "The Island.zip". 对于到目前为止的代码,originalFileName类似于“The Island.zip”。 Inside the zip there is a folder called The Island. 在拉链内有一个名为The Island的文件夹。 I need to find the folder inside the zip file that matches the zip file's name, and extract everything inside that. 我需要在zip文件中找到与zip文件名称匹配的文件夹,并提取其中的所有内容。

A much easier way to do that is using the NIO API of Java 7. I've just done that for one of my projects: 更简单的方法是使用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;
        }
    });
}

Voilà. 瞧。 Much cleaner than using ZipFile and ZipEntry , and it has the additional benefit of being re-usable for copying folder structure from ANY type of file system, not only for zip files. 比使用ZipFileZipEntryZipFile得多,它还具有可重复使用从任何类型的文件系统复制文件夹结构的额外好处,不仅适用于zip文件。

The path(folder) for the file is part of what "zipEntry.getName()" returns, and should get you the information you need as far as knowing if files are in the folder you seek. 该文件的路径(文件夹)是“zipEntry.getName()”返回的一部分,并且应该知道您所需的信息是否知道文件是否在您寻找的文件夹中。

I would do something like: 我会做的事情如下:

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 has a getInputStream method to get the input stream for the given ZipEntry, so, something like so: ZipFile有一个getInputStream方法来获取给定ZipEntry的输入流,所以,像这样:

InputStream instream = zipFile.getInputStream(ze);

Then read the bytes from the stream and write them to a file. 然后从流中读取字节并将其写入文件。

If you need your code to walk 1+ levels deep into sub directories, you can do something like this. 如果您需要将代码深入到子目录中,可以执行类似的操作。 Obviously this will not compile, but you get the idea. 显然这不会编译,但你明白了。 The method calls itself, and returns to itself making it possible to walk as deep as necessary into sub folders. 该方法调用自身,并返回自身,使得可以根据需要走到子文件夹中。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM