【问题标题】:Unzipping Multiple Files - Java解压缩多个文件 - Java
【发布时间】:2019-11-22 06:46:53
【问题描述】:

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

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

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

【问题讨论】:

    标签: java caching zip


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 谢谢,我能够以此为基础解压并解决我的问题!你是炸弹!
    • readAllBytes 不是很好,最好使用input.transferTo(output)
    猜你喜欢
    • 2015-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 2011-10-30
    • 2022-07-27
    • 1970-01-01
    相关资源
    最近更新 更多