Java ZIP - 如何解压缩文件夹?

Way*_*int 18 java zip

有没有示例代码,如何将ZIP文件夹解压缩到我想要的目录?我已将文件夹"FOLDER"中的所有文件读入字节数组,如何从其文件结构中重新创建?

sfr*_*frj 30

我不确定你的意思是什么?你的意思是没有API帮助自己做吗?

在你不介意使用一些开源库的情况下,有一个很酷的API,称为zip4J

它易于使用,我认为有很好的反馈.看这个例子:

String source = "folder/source.zip";
String destination = "folder/source/";   

try {
    ZipFile zipFile = new ZipFile(source);
    zipFile.extractAll(destination);
} catch (ZipException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

如果要解压缩的文件有密码,可以试试这个:

String source = "folder/source.zip";
String destination = "folder/source/";
String password = "password";

try {
    ZipFile zipFile = new ZipFile(source);
    if (zipFile.isEncrypted()) {
        zipFile.setPassword(password);
    }
    zipFile.extractAll(destination);
} catch (ZipException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

我希望这很有用.


小智 22

这是我正在使用的代码.根据您的需要更改BUFFER_SIZE.

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public final class ZipUtils {

    private static final int BUFFER_SIZE = 4096;

    public static void extract(ZipInputStream zip, File target) throws IOException {
        try {
            ZipEntry entry;

            while ((entry = zip.getNextEntry()) != null) {
                File file = new File(target, entry.getName());

                if (!file.toPath().normalize().startsWith(target.toPath())) {
                    throw new IOException("Bad zip entry");
                }

                if (entry.isDirectory()) {
                    file.mkdirs();
                    continue;
                }

                byte[] buffer = new byte[BUFFER_SIZE];
                file.getParentFile().mkdirs();
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
                int count;

                while ((count = zip.read(buffer)) != -1) {
                    out.write(buffer, 0, count);
                }

                out.close();
            }
        } finally {
            zip.close();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 你不应该吞下IOException. (4认同)

Oli*_*liv 15

一个最简洁、无库的 Java 7+ 变体:

public static void unzip(InputStream is, Path targetDir) throws IOException {
    targetDir = targetDir.toAbsolutePath();
    try (ZipInputStream zipIn = new ZipInputStream(is)) {
        for (ZipEntry ze; (ze = zipIn.getNextEntry()) != null; ) {
            Path resolvedPath = targetDir.resolve(ze.getName()).normalize();
            if (!resolvedPath.startsWith(targetDir)) {
                // see: https://snyk.io/research/zip-slip-vulnerability
                throw new RuntimeException("Entry with an illegal path: " 
                        + ze.getName());
            }
            if (ze.isDirectory()) {
                Files.createDirectories(resolvedPath);
            } else {
                Files.createDirectories(resolvedPath.getParent());
                Files.copy(zipIn, resolvedPath);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

createDirectories需要在两个分支,因为zip文件并不总是包含所有的父目录作为一个单独的项目,但可能包含它们仅代表空目录。

该代码解决了ZIP-slip 漏洞,如果某些 ZIP 条目超出targetDir. 此类 ZIP 不是使用常用工具创建的,很可能是手工制作以利用该漏洞。

  • 这很好。请注意,它不涵盖其他类型的 zip 漏洞,例如 zip 炸弹。因此,如果您接受来自未知/不可信来源的 zip 文件,请务必阅读 zip 漏洞并涵盖所有最常见的漏洞。 (2认同)

Kum*_*hav 11

使用Ant Compress库可以实现相同.它将保留文件夹结构.

Maven依赖: -

<dependency>
    <groupId>org.apache.ant</groupId>
    <artifactId>ant-compress</artifactId>
    <version>1.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

示例代码: -

Unzip unzipper = new Unzip();
unzipper.setSrc(theZIPFile);
unzipper.setDest(theTargetFolder);
unzipper.execute();
Run Code Online (Sandbox Code Playgroud)


Ale*_*aev 0

您应该从 zip 文件中获取所有条目:

Enumeration entries = zipFile.getEntries();
Run Code Online (Sandbox Code Playgroud)

然后迭代这个枚举从中获取ZipEntry,检查它是否是一个目录,然后分别创建目录或仅提取文件。