解压缩多个文件 - Java

Unzipping Multiple Files - Java

我正在为一个游戏客户端开发一个自动更新程序,我 运行 遇到了一个问题。

我需要它做什么:下载 cache.zip 和 client.zip。将 cache.zip 提取到 cacheDir 并将 client.zip 提取到与 运行 jar(游戏)相同的位置。

它现在做什么:同时下载 cache.zip 和 client.zip。将 cache.zip 提取到正确的位置,同时也提取到 jar 所在的位置。它根本不提取 client.zip。

我用这个函数解压一个文件:

public static void unzip(final ZipFile source, final File destination) throws IOException {
    for (final ZipEntry entry : Collections.list(source.entries())) {
        unzip(source, entry, destination);
    }
}

private static void unzip(final ZipFile source, final ZipEntry entry, final File destination) throws IOException {
    if (!entry.isDirectory()) {
        final File resource = new File(destination, entry.getName());
        if (!resource.getCanonicalPath().startsWith(destination.getCanonicalPath() + File.separator)) {
            throw new IOException("Entry is outside of the target dir: " + entry);
        }

        final File folder = resource.getParentFile();
        if (!folder.exists()) {
            if (!folder.mkdirs()) {
                throw new IOException();
            }
        }

        try (final BufferedInputStream input = new BufferedInputStream(source.getInputStream(entry));
             final BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(resource))) {
            output.write(input.readAllBytes());
            output.flush();
        }
    }
}

这里有一些重载:

public static void unzip(final String file) throws IOException {
    final File source = new File(file);
    unzip(
            new ZipFile(source),
            new File(source.getParent(), source.getName().substring(0, source.getName().lastIndexOf('.')))
    );
}

public static void unzip(final String source, final String destination) throws IOException {
    unzip(new File(source), new File(destination));
}

public static void unzip(final File source, final File destination) throws IOException {
    unzip(new ZipFile(source), destination);
}

注:

  • 它忽略空目录。如果需要,您可以添加 else 和 mkdir 条目。

  • 如果您需要加速进程,您可以在 unzip(final ZipFile source, final File destination) 上添加一个线程池,用于使用多个线程调用 unzip(final ZipFile source, final ZipEntry entry, final File destination)

  • unzip(final ZipFile source, final ZipEntry entry, final File destination) 正在检查每个条目是否输出的规范路径从目的地的规范路径开始以避免 Zip Slip Vulnerability - 请参阅 https://snyk.io/research/zip-slip-vulnerability -但是你可以忽略这个检查你的用例。

如果您需要获取 jar 库:

String fileRepertory = Setup.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();

最后,如果你需要压缩一个文件(我post它在这里作为我自己的备份^^')

public static void zip(final File destination, final List<File> toZip) throws IOException {
    try (final ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(destination))) {
        for (final File file : toZip) {
            final ZipEntry entry = new ZipEntry(file.getCanonicalPath());
            zip.putNextEntry(entry);
            zip.write(Files.readAllBytes(file.toPath()));
        }
    }
}