您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
三六零分类信息网 > 朝阳分类信息网,免费分类信息发布

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

2025/11/9 20:28:12发布97次查看
前言在一些日常业务中,会遇到一些琐碎文件需要统一打包到一个压缩包中上传,业务方在后台接收到压缩包后自行解压,然后解析相应文件。而且可能涉及安全保密,因此会在压缩时带上密码,要求后台业务可以指定密码进行解压。
应用环境说明:jdk1.8,maven3.x,需要基于java语言实现对zip、rar、7z等常见压缩包的解压工作。
首先关于zip和rar、7z等压缩工具和压缩算法就不在此赘述,下面通过一个数据对比,使用上述三种不同的压缩算法,采用默认的压缩方式,看到压缩的文件大小如下:
转换成图表看得更直观,如下图:
从以上图表可以看到,7z的压缩率是最高,而zip压缩率比较低,rar比zip稍微好点。单纯从压缩率看,7z>rar4>rar5>zip。
实现代码下面具体说明在java中如何进行相应解压:
1、pom.xml<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.yelang</groupid> <artifactid>7zdemo</artifactid> <version>0.0.1-snapshot</version> <dependencies> <dependency> <groupid>net.lingala.zip4j</groupid> <artifactid>zip4j</artifactid> <version>2.9.0</version> </dependency> <dependency> <groupid>net.sf.sevenzipjbinding</groupid> <artifactid>sevenzipjbinding</artifactid> <version>16.02-2.01</version> </dependency> <dependency> <groupid>net.sf.sevenzipjbinding</groupid> <artifactid>sevenzipjbinding-all-platforms</artifactid> <version>16.02-2.01</version> </dependency> <dependency> <groupid>org.tukaani</groupid> <artifactid>xz</artifactid> <version>1.9</version> </dependency> <dependency> <groupid>org.apache.commons</groupid> <artifactid>commons-compress</artifactid> <version>1.21</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupid>org.slf4j</groupid> <artifactid>slf4j-api</artifactid> <version>1.7.30</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupid>org.apache.commons</groupid> <artifactid>commons-lang3</artifactid> <version>3.12.0</version> </dependency> <!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/xdocreport --> <dependency> <groupid>fr.opensagres.xdocreport</groupid> <artifactid>xdocreport</artifactid> <version>1.0.6</version> </dependency> </dependencies></project>
主要依赖的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<string,object> unfile(string rootpath, string sourcepath, string destdirpath, string password) { map<string,object> resultmap = new hashmap<string, object>(); 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文件的解压统一算法。并对比了相应的解压速度,支持传入密码进行在线解压。
本文参考代码在补充内容里,不过代码直接运行有问题,这里进行了调整,主要优化的点如下:
1、pom.xml 遗漏了slf4j、commons-lang3、xdocreport等依赖
2、zip路径优化
3、去掉一些无用信息
4、优化异常信息
补充1.maven引用
<dependency> <groupid>net.lingala.zip4j</groupid> <artifactid>zip4j</artifactid> <version>2.9.0</version></dependency> <dependency> <groupid>net.sf.sevenzipjbinding</groupid> <artifactid>sevenzipjbinding</artifactid> <version>16.02-2.01</version></dependency><dependency> <groupid>net.sf.sevenzipjbinding</groupid> <artifactid>sevenzipjbinding-all-platforms</artifactid> <version>16.02-2.01</version></dependency> <dependency> <groupid>org.tukaani</groupid> <artifactid>xz</artifactid> <version>1.9</version></dependency><dependency> <groupid>org.apache.commons</groupid> <artifactid>commons-compress</artifactid> <version>1.21</version></dependency>
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如何解压带密码的zip、rar、7z文件?的详细内容。
朝阳分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product