JAVA之ZIP、RAR解压工具类
废话不多说直接上代码
1.相关依赖pom
<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>
2.解压压缩文件工具类
import net.sf.sevenzipjbinding.IInArchive; import net.sf.sevenzipjbinding.SevenZip; import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.io.*; import java.nio.charset.Charset; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream;public class UnZipAndRarUtil {private static Logger logger = LoggerFactory.getLogger(UnZipAndRarUtil.class);private static final int BUFFER_SIZE = 2 * 1024;/*** 压缩成ZIP 方法1** @param srcDir 压缩文件夹路径* @param out 压缩文件输出流* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;* false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)* @throws RuntimeException 压缩失败会抛出运行时异常*/public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) {long start = System.currentTimeMillis();ZipOutputStream zos = null;try {zos = new ZipOutputStream(out);File sourceFile = new File(srcDir);compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);long end = System.currentTimeMillis();logger.debug("压缩完成,耗时:" + (end - start) + " ms");} catch (Exception e) {throw new RuntimeException("zip error from ZipUtils", e);} finally {if (zos != null) {try {zos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 压缩成ZIP 方法2** @param srcFiles 需要压缩的文件列表* @param out 压缩文件输出流* @throws RuntimeException 压缩失败会抛出运行时异常*/public static void toZip(List<File> srcFiles, OutputStream out) {long start = System.currentTimeMillis();HashMap<Object, Object> index = new HashMap<>();int count = 0;ZipOutputStream zos = null;try {zos = new ZipOutputStream(out);for (File srcFile : srcFiles) {String fileName = srcFile.getName();logger.debug("压缩文件名称信息:{}", fileName);byte[] buf = new byte[BUFFER_SIZE];//解决文件重名导致压缩失败问题if (index.containsKey(fileName)) {count++;zos.putNextEntry(new ZipEntry("(" + count + ")" + "-" + srcFile.getName()));index.put("(" + count + ")" + "-" + srcFile.getName(), true);} else {zos.putNextEntry(new ZipEntry(srcFile.getName()));index.put(srcFile.getName(), true);}int len;FileInputStream in = new FileInputStream(srcFile);while ((len = in.read(buf)) != -1) {zos.write(buf, 0, len);}zos.closeEntry();in.close();srcFile.delete();}long end = System.currentTimeMillis();logger.info("压缩完成,耗时:" + (end - start) + " ms");} catch (Exception e) {throw new RuntimeException("zip error from ZipUtils", e);} finally {if (zos != null) {try {zos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 递归压缩方法** @param sourceFile 源文件* @param zos zip输出流* @param name 压缩后的名称* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;* false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)* @throws Exception*/private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) {try {byte[] buf = new byte[BUFFER_SIZE];if (sourceFile.isFile()) {// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字zos.putNextEntry(new ZipEntry(name));// copy文件到zip输出流中int len;FileInputStream in = new FileInputStream(sourceFile);while ((len = in.read(buf)) != -1) {zos.write(buf, 0, len);}zos.closeEntry();in.close();} else {File[] listFiles = sourceFile.listFiles();if (listFiles == null || listFiles.length == 0) {// 需要保留原来的文件结构时,需要对空文件夹进行处理if (KeepDirStructure) {// 空文件夹的处理zos.putNextEntry(new ZipEntry(name + "/"));// 没有文件,不需要文件的copyzos.closeEntry();}} else {for (File file : listFiles) {// 判断是否需要保留原来的文件结构if (KeepDirStructure) {// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了compress(file, zos, name + "/" + file.getName(), KeepDirStructure);} else {compress(file, zos, file.getName(), KeepDirStructure);}}}}} catch (IOException e) {e.printStackTrace();}}/*** <功能描述:> 解压文件到指定目录** @param zipFile zip文件* @param descDir 目标目录* @param levelDepth 解压的最大层级* @return void*/@SuppressWarnings("rawtypes")public static int unPackZip(File zipFile, String descDir, int levelDepth) {int unzipFileNum = 0;try {if (!descDir.endsWith("/")) {descDir = descDir + "/";}File pathFile = new File(descDir);if (!pathFile.exists()) {pathFile.mkdirs();}// 解决zip文件中有中文目录或者中文文件ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {ZipEntry entry = (ZipEntry) entries.nextElement();String zipEntryName = entry.getName();OutputStream out = null;try (InputStream in = zip.getInputStream(entry)) {// 文件名特殊处理String fileEnd = "";if (zipEntryName.contains("/")) {fileEnd = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);} else {fileEnd = entry.getName();}zipEntryName = zipEntryName.substring(0, zipEntryName.lastIndexOf('/') + 1) + fileEnd;String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");// 判断路径是否存在,不存在则创建文件路径File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));if (!file.exists()) {file.mkdirs();}// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压if (new File(outPath).isDirectory()) {continue;}// 获取当前层级int currentLevel = getCurrentLevel(descDir, outPath);if (currentLevel <= levelDepth) {++unzipFileNum;out = new FileOutputStream(outPath);byte[] buf1 = new byte[1024];int len;while ((len = in.read(buf1)) > 0) {out.write(buf1, 0, len);}//输出文件路径信息logger.info(String.format("解压ZIP文件= [%s] 中的文件路径[%s]!", zipFile.getName(), outPath));}} catch (Exception e) {logger.error(String.format("解压ZIP文件= [%s] 中的文件出错!", zipFile.getName()), e);} finally {if (null != out) {out.close();}}}zip.close();logger.info(String.format("解压[%s]文件,共解压出文件=[%s]个文件!", zipFile.getName(), unzipFileNum));} catch (IOException e) {logger.error("解压异常:{}", e);}return unzipFileNum;}private static int getCurrentLevel(String descDir, String outPath) {int currentLevel = 0;String innnerPath = outPath.substring(descDir.length());String[] folderArray = innnerPath.split("/");if (null != folderArray && folderArray.length > 1) {currentLevel = folderArray.length - 1;}return currentLevel;}public static int unRarFiles(File rarFile, String descDir) {if (!descDir.endsWith("/")) {descDir = descDir + "/";}File pathFile = new File(descDir);if (!pathFile.exists()) {pathFile.mkdirs();}try {// 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile//r代表以只读的方式打开文本,也就意味着不能用write来操作文件RandomAccessFile randomAccessFile = new RandomAccessFile(rarFile.toString(), "r");// null - autodetectIInArchive archive = SevenZip.openInArchive(null,new RandomAccessFileInStream(randomAccessFile));int[] in = new int[archive.getNumberOfItems()];for (int i = 0; i < in.length; i++) {in[i] = i;}AtomicInteger fileSum = new AtomicInteger(0);archive.extract(in, false, new ExtractCallback(archive, pathFile.getAbsolutePath() + "/"));archive.close();randomAccessFile.close();return fileSum.get();} catch (Exception e) {logger.error("解压rar出错 {}", e.getMessage());}return 0;}// public static void main(String[] args) throws Exception { // String zipFilepath = "D:\\工作内容.zip"; // unPackZip(new File(zipFilepath), null, "D:\\data\\fy\\"); // } }
3.创建提取文件实现类(IInArchive类属于SevenZip.Archive包)
import net.sf.sevenzipjbinding.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.io.*;public class ExtractCallback implements IArchiveExtractCallback {private static Logger log = LoggerFactory.getLogger(ExtractCallback.class);private int index;private IInArchive inArchive;private String ourDir;public ExtractCallback(IInArchive inArchive, String ourDir) {this.inArchive = inArchive;this.ourDir = ourDir;}@Overridepublic void setCompleted(long arg0) throws SevenZipException {}@Overridepublic void setTotal(long arg0) throws SevenZipException {}@Overridepublic ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {this.index = index;String path = (String) inArchive.getProperty(index, PropID.PATH);final boolean isFolder = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);String finalPath = path;File newfile = null;try {String fileEnd = "";//对文件名,文件夹特殊处理if (finalPath.contains(File.separator)) {fileEnd = finalPath.substring(finalPath.lastIndexOf(File.separator) + 1);} else {fileEnd = finalPath;}finalPath = finalPath.substring(0, finalPath.lastIndexOf(File.separator) + 1) + fileEnd;//目录层级finalPath = finalPath.replaceAll("\\\\", "/");String suffixName = "";int suffixIndex = fileEnd.lastIndexOf(".");if (suffixIndex != -1) {suffixName = fileEnd.substring(suffixIndex + 1);}newfile = createFile(isFolder, ourDir + finalPath);final boolean directory = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);} catch (Exception e) {log.error("rar解压失败{}", e.getMessage());}File finalFile = newfile;return data -> {save2File(finalFile, data);return data.length;};}@Overridepublic void prepareOperation(ExtractAskMode arg0) throws SevenZipException {}@Overridepublic void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {}public static File createFile(boolean isFolder, String path) {//前置是因为空文件时不会创建文件和文件夹File file = new File(path);try {if (!isFolder) {File parent = file.getParentFile();if ((!parent.exists())) {parent.mkdirs();}if (!file.exists()) {file.createNewFile();}} else {if ((!file.exists())) {file.mkdirs();}}} catch (Exception e) {log.error("rar创建文件或文件夹失败 {}", e.getMessage());}return file;}public static boolean save2File(File file, byte[] msg) {OutputStream fos = null;try {fos = new FileOutputStream(file, true);fos.write(msg);fos.flush();return true;} catch (FileNotFoundException e) {log.error("rar保存文件失败{}", e.getMessage());return false;} catch (IOException e) {log.error("rar保存文件失败{}", e.getMessage());return false;} finally {try {fos.close();} catch (IOException e) {log.error("rar保存文件失败{}", e.getMessage());}}}
JAVA之ZIP、RAR解压工具类相关推荐
- Java中zip压缩解压
1. 解压问题 360压缩文件 使用jdk API 读取压缩文件后解压,报错 java.lang.IllegalArgumentException:MALFORMED 如果是好压压缩文件,使用jdk ...
- JAVA常见压缩包解压工具类(支持:zip、7z和rar)
一.pom依赖 <groupId>org.apache.commons</groupId><artifactId>commons-compress</arti ...
- 【文件压缩解压工具类-含密码】
文件压缩解压工具类-含密码 一.zip4j简介 二.zip4j工具类使用步骤 1.添加maven依赖 2.工具类代码 3.调用测试 三.结语 一.zip4j简介 zip4j功能比较强大,支持加密.解密 ...
- Java实现Zip文件解压
2019独角兽企业重金招聘Python工程师标准>>> ##1. 两种java实现zip文件解压方式 使用JDK的原生类java.util.zip,上代码: import java. ...
- linux 下安装rar解压软件,centos下rar解压工具的安装 rar和unrar命令使用方法
安装rar解压工具我们需要先找到rar的工具包,rar的官方下载地址如下: //www.rarsoft.com/download 找到相对应的压缩包地址 我的是centos 64位的,我需要的地址压缩 ...
- linux解压工具软件,linux 安装rar解压工具
linux中默认的tar命令用于解压压缩文件,但是tar命令不支持rar文件的解压和压缩,需要安装rar解压工具,实现rar命令解压rar压缩包. 1.下载rarlab软件wget -c https: ...
- linux 安装rar解压工具
linux中默认的tar命令用于解压压缩文件,但是tar命令不支持rar文件的解压和压缩,需要安装rar解压工具,实现rar命令解压rar压缩包. 1.下载rarlab软件 官网下载页面:https: ...
- java的tgz解压工具类
前言 之前在代码上一直使用的是对zip的解压,最近对接方居然使用了tgz的压缩包,在网上找了一个工具类,在项目测试,使用. 直接贴上tgz解压代码. public class PackDecompre ...
- java.util.zip.ZipFile解压后被java占用问题。
在使用jdk自带zip解压工具解压文件时,调用ZipFile的getInputStream(ZipEntry entry)方法获取实体输入流后,正常关闭getInputStram返回的输入流.zip文 ...
- ubuntu下rar解压工具安装方法
1.压缩功能 安装 sudo apt-get install rar 卸载 sudo apt-get remove rar 2.解压功能 安装 sudo apt-get install unrar 卸 ...
最新文章
- python︱HTML网页解析BeautifulSoup学习笔记
- (python的坑,坑的我头晕,下行循环写后根遍历)
- Cisco IOS防火墙的安全规则和配置方案
- 有望年底登场!小米12系列即将备案:骁龙895+2亿像素!
- gprs模块http mqtt_GPRS模块用TCP实现MQTT协议(基于SIM900A)
- 自动服务器批量装机,PXE高效批量网络装机
- docker 拷贝镜像文件
- Atitit 网络协议概论 艾提拉著作 目录 1. 有的模型分七层,有的分四层。我觉得	1 1.1. 三、链接层 确定了0和1的分组方式	1 1.2. 网络层(ip mac转换层	3 1.3. 传输
- java中接口(interface)及使用方法和注意事项
- @18. 自幂数、水仙花数、四叶玫瑰数等等是什么?
- 数据分析的年度工作计划,这样制定才合理!
- 【CV】ViT:用于大规模图像识别的 Transformer
- js对日期加减指定天、时、分、秒
- JPEG系列二 JPEG文件中的EXIF(上)
- Android手机扫描,电脑复制内容----手机实现无线扫码枪功能
- 消息中间件ActiveMQ 4: 传输协议
- 华为od机考真题-HJ95人民币转换(较难)
- 关于无法修改本地Hosts文件解决办法
- 会员储值卡系统 java_java毕业设计_springboot框架的储值卡会员管理系统
- 2020年出生人口会大跌吗?解读人口数据
热门文章
- 思科路由器虚拟服务器,解读CISCO路由器基本设置方法
- 【课程作业】学术英语写作:文献阅读报告1
- 晶振外匹配电容应该怎样选取
- 24个希腊字母(符号) 附字母表
- 适合初中文凭学的计算机技术,初中毕业学啥技术好 最吃香的手艺
- 傅里叶分析 [作 者:韩 昊]
- java+mail+authen_JavaMail - 身份验证( Authentication)
- 樊登读书会终身成长读后感_樊登读书会创始人演讲《知识爆炸时代如何终身成长》...
- wiFI基础知识----wpa_supplicant
- 计算机二级office易错知识点,重要!!!计算机二级office易错点汇总