Java怎么对zip,rar,7z文件带密码解压(java,开发技术)

时间:2024-05-09 16:38:49 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

前言

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

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

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

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

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

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

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

实现代码

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

1、pom.xml

<projectxmlns="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.0http://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")privatestaticStringunZip(StringrootPath,StringsourceRarPath,StringdestDirPath,StringpassWord){ZipFilezipFile=null;Stringresult="";try{//StringfilePath=sourceRarPath;StringfilePath=rootPath+sourceRarPath;if(StringUtils.isNotBlank(passWord)){zipFile=newZipFile(filePath,passWord.toCharArray());}else{zipFile=newZipFile(filePath);}zipFile.setCharset(Charset.forName("GBK"));zipFile.extractAll(rootPath+destDirPath);}catch(Exceptione){log.error("unZiperror",e);returne.getMessage();}returnresult;}

3、rar解压

privatestaticStringunRar(StringrootPath,StringsourceRarPath,StringdestDirPath,StringpassWord){StringrarDir=rootPath+sourceRarPath;StringoutDir=rootPath+destDirPath+File.separator;RandomAccessFilerandomAccessFile=null;IInArchiveinArchive=null;try{//第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFilerandomAccessFile=newRandomAccessFile(rarDir,"r");if(StringUtils.isNotBlank(passWord))inArchive=SevenZip.openInArchive(null,newRandomAccessFileInStream(randomAccessFile),passWord);elseinArchive=SevenZip.openInArchive(null,newRandomAccessFileInStream(randomAccessFile));ISimpleInArchivesimpleInArchive=inArchive.getSimpleInterface();for(finalISimpleInArchiveItemitem:simpleInArchive.getArchiveItems()){finalint[]hash=newint[]{0};if(!item.isFolder()){ExtractOperationResultresult;finallong[]sizeArray=newlong[1];FileoutFile=newFile(outDir+item.getPath());Fileparent=outFile.getParentFile();if((!parent.exists())&&(!parent.mkdirs())){continue;}if(StringUtils.isNotBlank(passWord)){result=item.extractSlow(data->{try{IOUtils.write(data,newFileOutputStream(outFile,true));}catch(Exceptione){e.printStackTrace();}hash[0]^=Arrays.hashCode(data);//ConsumedatasizeArray[0]+=data.length;returndata.length;//Returnamountofconsumed},passWord);}else{result=item.extractSlow(data->{try{IOUtils.write(data,newFileOutputStream(outFile,true));}catch(Exceptione){e.printStackTrace();}hash[0]^=Arrays.hashCode(data);//ConsumedatasizeArray[0]+=data.length;returndata.length;//Returnamountofconsumed});}if(result==ExtractOperationResult.OK){log.error("解压rar成功...."+String.format("%9X|%10s|%s",hash[0],sizeArray[0],item.getPath()));}elseif(StringUtils.isNotBlank(passWord)){log.error("解压rar成功:密码错误或者其他错误...."+result);return"password";}else{return"rarerror";}}}}catch(Exceptione){log.error("unRarerror",e);returne.getMessage();}finally{try{inArchive.close();randomAccessFile.close();}catch(Exceptione){e.printStackTrace();}}return"";}

4、7z解压

privatestaticStringun7z(StringrootPath,StringsourceRarPath,StringdestDirPath,StringpassWord){try{FilesrcFile=newFile(rootPath+sourceRarPath);//获取当前压缩文件//判断源文件是否存在if(!srcFile.exists()){thrownewException(srcFile.getPath()+"所指文件不存在");}//开始解压SevenZFilezIn=null;if(StringUtils.isNotBlank(passWord)){zIn=newSevenZFile(srcFile,passWord.toCharArray());}else{zIn=newSevenZFile(srcFile);}SevenZArchiveEntryentry=null;Filefile=null;while((entry=zIn.getNextEntry())!=null){if(!entry.isDirectory()){file=newFile(rootPath+destDirPath,entry.getName());if(!file.exists()){newFile(file.getParent()).mkdirs();//创建此文件的上级目录}OutputStreamout=newFileOutputStream(file);BufferedOutputStreambos=newBufferedOutputStream(out);intlen=-1;byte[]buf=newbyte[1024];while((len=zIn.read(buf))!=-1){bos.write(buf,0,len);}//关流顺序,先打开的后关闭bos.close();out.close();}}}catch(Exceptione){log.error("un7ziserror",e);returne.getMessage();}return"";}

5、解压统一入口封装

publicstaticMap<String,Object>unFile(StringrootPath,StringsourcePath,StringdestDirPath,StringpassWord){Map<String,Object>resultMap=newHashMap<String,Object>();Stringresult="";if(sourcePath.toLowerCase().endsWith(".zip")){//Wrongpassword!result=unZip(rootPath,sourcePath,destDirPath,passWord);}elseif(sourcePath.toLowerCase().endsWith(".rar")){//java.security.InvalidAlgorithmParameterException:passwordshouldbespecifiedresult=unRar(rootPath,sourcePath,destDirPath,passWord);System.out.println(result);}elseif(sourcePath.toLowerCase().endsWith(".7z")){//PasswordRequiredException:CannotreadencryptedcontentfromG:\ziptest\11111111.7zwithoutapasswordresult=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+"==============");returnresultMap;}

6、测试代码

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

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

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

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

总结:本文采用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.实现代码如下

importfr.opensagres.xdocreport.core.io.IOUtils;importnet.lingala.zip4j.ZipFile;importnet.sf.sevenzipjbinding.*;importnet.sf.sevenzipjbinding.impl.RandomAccessFileInStream;importnet.sf.sevenzipjbinding.simple.ISimpleInArchive;importnet.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;importorg.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;importorg.apache.commons.compress.archivers.sevenz.SevenZFile;importorg.apache.commons.lang3.StringUtils;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.io.*;importjava.util.*;publicclassZipAndRarTools{privatestaticfinalLoggerlog=LoggerFactory.getLogger(ZipAndRarTools.class);/*解压zip*/privatestaticStringunZip(StringrootPath,StringsourceRarPath,StringdestDirPath,StringpassWord){ZipFilezipFile=null;try{if(StringUtils.isNotBlank(passWord)){zipFile=newZipFile(filePath,passWord.toCharArray());}else{zipFile=newZipFile(filePath);}zipFile.extractAll(rootPath+destDirPath);}catch(Exceptione){log.error("unZiperror",e);returne.getMessage();}return"";}/*解压rarrar5*/privatestaticStringunRar(StringrootPath,StringsourceRarPath,StringdestDirPath,StringpassWord){/*finalFilerar=newFile(rootPath+sourceRarPath);finalFiledestinationFolder=newFile(rootPath+destDirPath);destinationFolder.mkdir();try{Junrar.extract(rar,destinationFolder);}catch(Exceptione){log.error("unRarerror",e);returne.getMessage();}*/StringrarDir=rootPath+sourceRarPath;StringoutDir=rootPath+destDirPath+File.separator;RandomAccessFilerandomAccessFile=null;IInArchiveinArchive=null;try{//第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFilerandomAccessFile=newRandomAccessFile(rarDir,"r");if(StringUtils.isNotBlank(passWord))inArchive=SevenZip.openInArchive(null,newRandomAccessFileInStream(randomAccessFile),passWord);elseinArchive=SevenZip.openInArchive(null,newRandomAccessFileInStream(randomAccessFile));ISimpleInArchivesimpleInArchive=inArchive.getSimpleInterface();for(finalISimpleInArchiveItemitem:simpleInArchive.getArchiveItems()){finalint[]hash=newint[]{0};if(!item.isFolder()){ExtractOperationResultresult;finallong[]sizeArray=newlong[1];FileoutFile=newFile(outDir+item.getPath());Fileparent=outFile.getParentFile();if((!parent.exists())&&(!parent.mkdirs())){continue;}if(StringUtils.isNotBlank(passWord)){result=item.extractSlow(data->{try{IOUtils.write(data,newFileOutputStream(outFile,true));}catch(Exceptione){e.printStackTrace();}hash[0]^=Arrays.hashCode(data);//ConsumedatasizeArray[0]+=data.length;returndata.length;//Returnamountofconsumed},passWord);}else{result=item.extractSlow(data->{try{IOUtils.write(data,newFileOutputStream(outFile,true));}catch(Exceptione){e.printStackTrace();}hash[0]^=Arrays.hashCode(data);//ConsumedatasizeArray[0]+=data.length;returndata.length;//Returnamountofconsumed});}if(result==ExtractOperationResult.OK){log.error("解压rar成功...."+String.format("%9X|%10s|%s",hash[0],sizeArray[0],item.getPath()));}elseif(StringUtils.isNotBlank(passWord)){log.error("解压rar成功:密码错误或者其他错误...."+result);return"password";}else{return"rarerror";}}}}catch(Exceptione){log.error("unRarerror",e);returne.getMessage();}finally{try{inArchive.close();randomAccessFile.close();}catch(Exceptione){e.printStackTrace();}}return"";}/**解压7z*/privatestaticStringun7z(StringrootPath,StringsourceRarPath,StringdestDirPath,StringpassWord){try{FilesrcFile=newFile(rootPath+sourceRarPath);//获取当前压缩文件//判断源文件是否存在if(!srcFile.exists()){thrownewException(srcFile.getPath()+"所指文件不存在");}//开始解压SevenZFilezIn=null;if(StringUtils.isNotBlank(passWord))newSevenZFile(srcFile,passWord.getBytes());elsenewSevenZFile(srcFile);SevenZArchiveEntryentry=null;Filefile=null;while((entry=zIn.getNextEntry())!=null){if(!entry.isDirectory()){file=newFile(rootPath+destDirPath,entry.getName());if(!file.exists()){newFile(file.getParent()).mkdirs();//创建此文件的上级目录}OutputStreamout=newFileOutputStream(file);BufferedOutputStreambos=newBufferedOutputStream(out);intlen=-1;byte[]buf=newbyte[1024];while((len=zIn.read(buf))!=-1){bos.write(buf,0,len);}//关流顺序,先打开的后关闭bos.close();out.close();}}}catch(Exceptione){log.error("un7ziserror",e);returne.getMessage();}return"";}publicstaticvoidunFile(StringrootPath,StringsourcePath,StringdestDirPath,StringpassWord){Stringresult="";if(sourcePath.toLowerCase().endsWith(".zip")){//Wrongpassword!result=unZip(rootPath,sourcePath,destDirPath,passWord);}elseif(sourcePath.toLowerCase().endsWith(".rar")){//java.security.InvalidAlgorithmParameterException:passwordshouldbespecifiedresult=unRar(rootPath,sourcePath,destDirPath,passWord);}elseif(sourcePath.toLowerCase().endsWith(".7z")){//PasswordRequiredException:CannotreadencryptedcontentfromG:\ziptest\11111111.7zwithoutapasswordresult=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+"==============");returnresultMap;}publicstaticvoidmain(String[]args){getFileList("G:\\ziptest\\","测试.zip","test3333","密码");}}
 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Java怎么对zip,rar,7z文件带密码解压的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:MySQL流程控制while,repeat,loop循环实例分析下一篇:

4 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18