0

0

Java如何解压带密码的zip、rar、7z文件?

王林

王林

发布时间:2023-04-24 14:04:07

|

3639人浏览过

|

来源于亿速云

转载

前言

在一些日常业务中,会遇到一些琐碎文件需要统一打包到一个压缩包中上传,业务方在后台接收到压缩包后自行解压,然后解析相应文件。而且可能涉及安全保密,因此会在压缩时带上密码,要求后台业务可以指定密码进行解压。

应用环境说明:jdk1.8,maven3.x,需要基于java语言实现对zip、rar、7z等常见压缩包的解压工作。

首先关于zip和rar、7z等压缩工具和压缩算法就不在此赘述,下面通过一个数据对比,使用上述三种不同的压缩算法,采用默认的压缩方式,看到压缩的文件大小如下:

Java怎么对zip,rar,7z文件带密码解压

转换成图表看得更直观,如下图:

立即学习Java免费学习笔记(深入)”;

Java怎么对zip,rar,7z文件带密码解压

从以上图表可以看到,7z的压缩率是最高,而zip压缩率比较低,rar比zip稍微好点。单纯从压缩率看,7z>rar4>rar5>zip。

实现代码

下面具体说明在java中如何进行相应解压:

1、pom.xml


    4.0.0
    com.yelang
    7zdemo
    0.0.1-SNAPSHOT
 
    
        
            net.lingala.zip4j
            zip4j
            2.9.0
        
 
        
            net.sf.sevenzipjbinding
            sevenzipjbinding
            16.02-2.01
        
        
            net.sf.sevenzipjbinding
            sevenzipjbinding-all-platforms
            16.02-2.01
        
 
        
            org.tukaani
            xz
            1.9
        
        
            org.apache.commons
            commons-compress
            1.21
        
        
        
        
            org.slf4j
            slf4j-api
            1.7.30
        
        
        
        
            org.apache.commons
            commons-lang3
            3.12.0
        
        
        
        
            fr.opensagres.xdocreport
            xdocreport
            1.0.6
        
        
    

主要依赖的jar包有:zip4j、sevenzipjbinding等。

2、zip解压

 @SuppressWarnings("resource")
private static String unZip(String rootPath, String sourceRarPath, String destDirPath, String passWord) {
        ZipFile zipFile = null;
        String result = "";
        try {
            //String filePath = sourceRarPath;
            String filePath = rootPath + sourceRarPath;
            if (StringUtils.isNotBlank(passWord)) {
                zipFile = new ZipFile(filePath, passWord.toCharArray());
            } else {
                zipFile = new ZipFile(filePath);
            }
            zipFile.setCharset(Charset.forName("GBK"));
            zipFile.extractAll(rootPath + destDirPath);
        } catch (Exception e) {
            log.error("unZip error", e);
            return e.getMessage();
        }
        return result;
    }

3、rar解压

private static String unRar(String rootPath, String sourceRarPath, String destDirPath, String passWord) {
        String rarDir = rootPath + sourceRarPath;
        String outDir = rootPath + destDirPath + File.separator;
        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        try {
            // 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile
            randomAccessFile = new RandomAccessFile(rarDir, "r");
            if (StringUtils.isNotBlank(passWord))
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile), passWord);
            else
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
 
            ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
            for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
                final int[] hash = new int[]{0};
                if (!item.isFolder()) {
                    ExtractOperationResult result;
                    final long[] sizeArray = new long[1];
 
                    File outFile = new File(outDir + item.getPath());
                    File parent = outFile.getParentFile();
                    if ((!parent.exists()) && (!parent.mkdirs())) {
                        continue;
                    }
                    if (StringUtils.isNotBlank(passWord)) {
                        result = item.extractSlow(data -> {
                            try {
                                IOUtils.write(data, new FileOutputStream(outFile, true));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed
                        }, passWord);
                    } else {
                        result = item.extractSlow(data -> {
                            try {
                                IOUtils.write(data, new FileOutputStream(outFile, true));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed
                        });
                    }
                    
                    if (result == ExtractOperationResult.OK) {
                        log.error("解压rar成功...." + String.format("%9X | %10s | %s", hash[0], sizeArray[0], item.getPath()));
                    } else if (StringUtils.isNotBlank(passWord)) {
                        log.error("解压rar成功:密码错误或者其他错误...." + result);
                        return "password";
                    } else {
                        return "rar error";
                    }
                }
            }
 
        } catch (Exception e) {
            log.error("unRar error", e);
            return e.getMessage();
        } finally {
            try {
                inArchive.close();
                randomAccessFile.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "";
    }

4、7z解压

 private static String un7z(String rootPath, String sourceRarPath, String destDirPath, String passWord) {
        try {
            File srcFile = new File(rootPath + sourceRarPath);//获取当前压缩文件
            // 判断源文件是否存在
            if (!srcFile.exists()) {
                throw new Exception(srcFile.getPath() + "所指文件不存在");
            }
            //开始解压
            SevenZFile zIn = null;
            if (StringUtils.isNotBlank(passWord)) {
                zIn = new SevenZFile(srcFile, passWord.toCharArray());
            }  else {
                zIn = new SevenZFile(srcFile);
            }
 
            SevenZArchiveEntry entry = null;
            File file = null;
            while ((entry = zIn.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    file = new File(rootPath + destDirPath, entry.getName());
                    if (!file.exists()) {
                        new File(file.getParent()).mkdirs();//创建此文件的上级目录
                    }
                    OutputStream out = new FileOutputStream(file);
                    BufferedOutputStream bos = new BufferedOutputStream(out);
                    int len = -1;
                    byte[] buf = new byte[1024];
                    while ((len = zIn.read(buf)) != -1) {
                        bos.write(buf, 0, len);
                    }
                    // 关流顺序,先打开的后关闭
                    bos.close();
                    out.close();
                }
            }
 
        } catch (Exception e) {
            log.error("un7z is error", e);
            return e.getMessage();
        }
        return "";
    }

5、解压统一入口封装

public static Map unFile(String rootPath, String sourcePath, String destDirPath, String passWord) {
        Map resultMap = new HashMap();
        String result = "";
        if (sourcePath.toLowerCase().endsWith(".zip")) {
            //Wrong password!
            result = unZip(rootPath, sourcePath, destDirPath, passWord);
        } else if (sourcePath.toLowerCase().endsWith(".rar")) {
            //java.security.InvalidAlgorithmParameterException: password should be specified
            result = unRar(rootPath, sourcePath, destDirPath, passWord);
            System.out.println(result);
        } else if (sourcePath.toLowerCase().endsWith(".7z")) {
            //PasswordRequiredException: Cannot read encrypted content from G:\ziptest\11111111.7z without a password
            result = un7z(rootPath, sourcePath, destDirPath, passWord);
        }
     
        resultMap.put("resultMsg", 1);
        if (StringUtils.isNotBlank(result)) {
            if (result.contains("password")) resultMap.put("resultMsg", 2);
            if (!result.contains("password")) resultMap.put("resultMsg", 3);
        }
        resultMap.put("files", null);
        //System.out.println(result + "==============");
        return resultMap;
    }

6、测试代码

Long start = System.currentTimeMillis();
unFile("D:/rarfetch0628/","apache-tomcat-8.5.69.zip","apache-tomcat-zip","222");
long end = System.currentTimeMillis();
System.out.println("zip解压耗时==" + (end - start) + "毫秒");
System.out.println("============================================================");
        
Long rar4start = System.currentTimeMillis();
unFile("D:/rarfetch0628/","apache-tomcat-8.5.69-4.rar","apache-tomcat-rar4","222");
long rar4end = System.currentTimeMillis();
System.out.println("rar4解压耗时==" + (rar4end - rar4start)+ "毫秒");
System.out.println("============================================================");
        
Long rar5start = System.currentTimeMillis();
unFile("D:/rarfetch0628/","apache-tomcat-8.5.69-5.rar","apache-tomcat-rar5","222");
long rar5end = System.currentTimeMillis();
System.out.println("rar5解压耗时==" + (rar5end - rar5start)+ "毫秒");
System.out.println("============================================================");
        
Long zstart = System.currentTimeMillis();
unFile("D:/rarfetch0628/","apache-tomcat-8.5.69.7z","apache-tomcat-7z","222");
long zend = System.currentTimeMillis();
System.out.println("7z解压耗时==" + (zend - zstart)+ "毫秒");
System.out.println("============================================================");

在控制台中可以看到以下结果:

Java怎么对zip,rar,7z文件带密码解压

爱之谷成人用品商城整站 for ECshop
爱之谷成人用品商城整站 for ECshop

这是网上分享的第一个带整站数据包的爱之谷模板,希望大家支持开发者“ecshop模板堂”安装方法:1,解压rar包上传到网站根目录2,导入sql数据库文件,到你的数据库里,可以phpmyadmin等软件3,修改data里config.php里面的数据库 用户名 密码等信息 为你自己的数据库信息4,安装完毕之后的后台用户名密码为:后台地址:域名/admin用户名

下载

Java怎么对zip,rar,7z文件带密码解压

总结:本文采用java语言实现了对zip和rar、7z文件的解压统一算法。并对比了相应的解压速度,支持传入密码进行在线解压。

本文参考代码在补充内容里,不过代码直接运行有问题,这里进行了调整,主要优化的点如下:

1、pom.xml 遗漏了slf4j、commons-lang3、xdocreport等依赖

2、zip路径优化

3、去掉一些无用信息

4、优化异常信息

补充

1.maven引用


   net.lingala.zip4j
   zip4j
   2.9.0

 

   net.sf.sevenzipjbinding
   sevenzipjbinding
   16.02-2.01


   net.sf.sevenzipjbinding
   sevenzipjbinding-all-platforms
   16.02-2.01

 

   org.tukaani
   xz
   1.9


    org.apache.commons
    commons-compress
    1.21

2.实现代码如下

import fr.opensagres.xdocreport.core.io.IOUtils;
import net.lingala.zip4j.ZipFile;
import net.sf.sevenzipjbinding.*;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.*;
 
 
public class ZipAndRarTools {
    private static final Logger log = LoggerFactory.getLogger(ZipAndRarTools.class);
 
    /*
    解压zip
    */
    private static String unZip(String rootPath, String sourceRarPath, String destDirPath, String passWord) {
        ZipFile zipFile = null;
 
        try {
 
            if (StringUtils.isNotBlank(passWord)) {
                zipFile = new ZipFile(filePath, passWord.toCharArray());
            } else {
                zipFile = new ZipFile(filePath);
            }
            zipFile.extractAll(rootPath + destDirPath);
        } catch (Exception e) {
            log.error("unZip error", e);
            return e.getMessage();
        }
        return "";
    }
 
 
    /*
       解压rar rar5
       */
    private static String unRar(String rootPath, String sourceRarPath, String destDirPath, String passWord) {
         /*final File rar = new File(rootPath + sourceRarPath);
       final File destinationFolder = new File(rootPath + destDirPath);
        destinationFolder.mkdir();
        try {
            Junrar.extract(rar, destinationFolder);
        } catch (Exception e) {
            log.error("unRar error", e);
            return e.getMessage();
        }*/
 
        String rarDir = rootPath + sourceRarPath;
        String outDir = rootPath + destDirPath + File.separator;
        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        try {
            // 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile
            randomAccessFile = new RandomAccessFile(rarDir, "r");
            if (StringUtils.isNotBlank(passWord))
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile), passWord);
            else
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
 
            ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
            for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
                final int[] hash = new int[]{0};
                if (!item.isFolder()) {
                    ExtractOperationResult result;
                    final long[] sizeArray = new long[1];
 
                    File outFile = new File(outDir + item.getPath());
                    File parent = outFile.getParentFile();
                    if ((!parent.exists()) && (!parent.mkdirs())) {
                        continue;
                    }
                    if (StringUtils.isNotBlank(passWord)) {
                        result = item.extractSlow(data -> {
                            try {
                                IOUtils.write(data, new FileOutputStream(outFile, true));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed
                        }, passWord);
                    } else {
                        result = item.extractSlow(data -> {
                            try {
                                IOUtils.write(data, new FileOutputStream(outFile, true));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            hash[0] ^= Arrays.hashCode(data); // Consume data
                            sizeArray[0] += data.length;
                            return data.length; // Return amount of consumed
                        });
                    }
 
                    if (result == ExtractOperationResult.OK) {
                        log.error("解压rar成功...." + String.format("%9X | %10s | %s", hash[0], sizeArray[0], item.getPath()));
                    } else if (StringUtils.isNotBlank(passWord)) {
                        log.error("解压rar成功:密码错误或者其他错误...." + result);
                        return "password";
                    } else {
                        return "rar error";
                    }
                }
            }
 
        } catch (Exception e) {
            log.error("unRar error", e);
            return e.getMessage();
        } finally {
            try {
                inArchive.close();
                randomAccessFile.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "";
    }
 
 
    /*
     * 解压7z
     */
    private static String un7z(String rootPath, String sourceRarPath, String destDirPath, String passWord) {
        try {
            File srcFile = new File(rootPath + sourceRarPath);//获取当前压缩文件
            // 判断源文件是否存在
            if (!srcFile.exists()) {
                throw new Exception(srcFile.getPath() + "所指文件不存在");
            }
            //开始解压
            SevenZFile zIn = null;
            if (StringUtils.isNotBlank(passWord))
                new SevenZFile(srcFile, passWord.getBytes());
            else
                new SevenZFile(srcFile);
 
            SevenZArchiveEntry entry = null;
            File file = null;
            while ((entry = zIn.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    file = new File(rootPath + destDirPath, entry.getName());
                    if (!file.exists()) {
                        new File(file.getParent()).mkdirs();//创建此文件的上级目录
                    }
                    OutputStream out = new FileOutputStream(file);
                    BufferedOutputStream bos = new BufferedOutputStream(out);
                    int len = -1;
                    byte[] buf = new byte[1024];
                    while ((len = zIn.read(buf)) != -1) {
                        bos.write(buf, 0, len);
                    }
                    // 关流顺序,先打开的后关闭
                    bos.close();
                    out.close();
                }
            }
 
        } catch (Exception e) {
            log.error("un7z is error", e);
            return e.getMessage();
        }
        return "";
    }
 
    public static void unFile(String rootPath, String sourcePath, String destDirPath, String passWord) {
        String result = "";
        if (sourcePath.toLowerCase().endsWith(".zip")) {
            //Wrong password!
            result = unZip(rootPath, sourcePath, destDirPath, passWord);
        } else if (sourcePath.toLowerCase().endsWith(".rar")) {
            //java.security.InvalidAlgorithmParameterException: password should be specified
            result = unRar(rootPath, sourcePath, destDirPath, passWord);
        } else if (sourcePath.toLowerCase().endsWith(".7z")) {
            //PasswordRequiredException: Cannot read encrypted content from G:\ziptest\11111111.7z without a password
            result = un7z(rootPath, sourcePath, destDirPath, passWord);
        }
     
        resultMap.put("resultMsg", 1);
        if (StringUtils.isNotBlank(result)) {
            if (result.contains("password")) resultMap.put("resultMsg", 2);
            if (!result.contains("password")) resultMap.put("resultMsg", 3);
        }
        resultMap.put("files", data);
//        System.out.println(result + "==============");
        return resultMap;
    }
 
 
    public static void main(String[] args) {
        getFileList("G:\\ziptest\\", "测试.zip", "test3333", "密码");
    }
 
}

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

3

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

7

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

30

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

2

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

8

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

3

2026.01.15

php图片上传教程汇总
php图片上传教程汇总

本专题整合了php图片上传相关教程,阅读专题下面的文章了解更多详细教程。

2

2026.01.15

phpstorm相关教程大全
phpstorm相关教程大全

本专题整合了phpstorm相关教程汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.5万人学习

C# 教程
C# 教程

共94课时 | 6.8万人学习

Java 教程
Java 教程

共578课时 | 46.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号