当前位置: 首页 > news >正文

如何通过 Java 来完成 zip 文件与 rar 文件的解压缩?

目录

一、用到的知识点

二、代码展示(分解版)

三、代码展示(整体版)


一、用到的知识点

1.IO流:

        Input:输入,通过“输入流”进行文件的读取操作

        Output:输出,通过“输出流”进行文件的写入操作

2.文件操作相关:

        File类:用于表示文件和目录的路径。

        FileInputStream和FileOutputStream:用于读取和写入文件。

3.压缩文件处理:

        ZipInputStream:用于读取 ZIP 压缩文件的输入流。

        ZipEntry:表示 ZIP 压缩文件中的条目(文件或目录)。

4.异常处理:

        FileNotFoundException:当尝试访问不存在的文件时抛出。

        IOException:用于处理输入输出操作中的一般性异常。

        RarException:处理与 RAR 压缩文件操作相关的特定异常。

5.数据输入输出流:

        InputStream:用于读取数据的输入流。

6.集合操作:

        List:用于存储文件头信息的列表。

7.比较器(Comparator):用于对文件头列表进行排序。

8.第三方库 commons-io 中的 FileUtils 类:(此jar包在文末)

       用于删除目录和复制输入流到文件。

二、代码展示(分解版)

步骤1:判断文件类型

  •         若是".zip"文件则调用unzip()方法来解压缩 ZIP 文件,若是".rar"文件则调用unrar()方法来解压缩 RAR 文件
//指定文件夹String Path = “D:\\...\\xxxx.zip”String Path = “D:\\...\\xxxx.rar”
}
//1.判断文件类型if(path.endsWith(".zip")) {unzip(path);}else if(path.endsWith(".rar")) {unrar(path);}	}

步骤2:定义unzip()方法

  • 根据输入的文件路径创建源文件对象。
  • 确定解压缩后的根目录路径,并创建对应的文件对象。
  • 如果根目录已存在,尝试删除(包括使用 FileUtils 工具类删除非空目录),然后重新创建根目录。
  • 创建用于读取 ZIP 格式的输入流。
  • 遍历压缩包中的每个条目(子文件或子目录)。
  • 为每个条目创建对应的文件对象。
  • 判断条目是子文件还是子目录,分别进行创建文件或目录的操作。
  • 对于子文件,创建输出流,读取输入流中的数据并写入子文件。
  • 处理可能出现的文件未找到和输入输出异常。
//2.解压缩zip格式public static void unzip(String path) {//(1)根据原始路径(字符串),创建源文件(File对象)File sourceFile = new File(path);//(2)根目录String sourceName = sourceFile.getName();File rootDir = new File(sourceFile.getParent()+"\\"+sourceName.substring(0,sourceName.lastIndexOf(".")));//(3)判断根目录是否已经存在if(rootDir.exists()) {//若存在,则删除rootDir.delete();//只能删除空目录//使用commons-io包提供的FileUtils工具类进行删除try {FileUtils.deleteDirectory(rootDir);} catch (IOException e) {e.printStackTrace();}}//(4)创建根目录rootDir.mkdir();//(5)ZipInputStream:用于进行zip格式的压缩输入流try {ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));//(6)遍历压缩包中每个子文件子目录(zipEntry类型的对象)ZipEntry zipEntry = null;while((zipEntry = in.getNextEntry())!=null) {//(7)创建子文件子目录(File对象)File file = new File(rootDir.getPath()+"\\"+zipEntry.getName());//(8)判断是子文件还是子目录(不是子目录就是子文件)if(zipEntry.isDirectory()) {//物理磁盘创建子目录file.mkdir();}else {//物理磁盘创建子文件file.createNewFile();//(9)子文件的写入//读取当前压缩包的子文件,并通过输出流out写入新子文件中try (FileOutputStream out = new FileOutputStream(file)) {byte[] buff = new byte[1024];int len = -1;while((len = in.read(buff))!=-1) {out.write(buff,0,len);}}}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

 步骤3:定义unrar()方法

  • 根据输入的 RAR 文件路径创建根目录的文件对象。
  • 判断根目录是否存在,如果存在则尝试删除(使用 FileUtils 处理可能的异常),然后创建根目录。
  • 创建用于读取 RAR 压缩文件的 Archive 对象。
  • 获取压缩文件中的所有子目录和子文件的 FileHeader 对象,并存储在列表中。
  • 按照子目录和子文件的名称对列表进行排序。
  • 遍历列表中的每个 FileHeader 对象。
  • 根据 FileHeader 对象创建对应的文件对象。
  • 判断是子目录还是子文件,分别进行创建目录或文件的操作。
  • 对于子文件,获取输入流并使用 FileUtils 将输入流复制到子文件中。
  • 处理可能出现的 RAR 相关异常和输入输出异常。
//3.解压缩rar格式public static void unrar(String path) {//(1)创建解压缩的根目录File rarFile = new File(path);File rootDir = new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));//(2)判断是否存在if(rootDir.exists()) {try {FileUtils.deleteDirectory(rootDir);} catch (IOException e) {e.printStackTrace();}}rootDir.mkdir();//(3)创建Archive对象,用于读取rar压缩文件格式try (Archive archive = new Archive(new FileInputStream(path))){//(4)获取压缩文件所有子目录子文件(FileHeader对象)List<FileHeader> fileheaderList = archive.getFileHeaders();//(5)按照子目录(子文件)名称排序fileheaderList.sort(new Comparator<FileHeader>() {@Overridepublic int compare(FileHeader o1, FileHeader o2) {return o1.getFileName().compareTo(o2.getFileName());}});//(6)遍历子目录子文件for(FileHeader fd : fileheaderList) {File f = new File(rootDir.getPath()+"\\"+fd.getFileName());if(fd.isDirectory()) {//物理磁盘创建子目录f.mkdir();}else {//物理磁盘创建子文件f.createNewFile();//获取压缩包中子文件输入流InputStream in = archive.getInputStream(fd);//复制文件输入流至子文件FileUtils.copyInputStreamToFile(in, f);}}} catch (RarException | IOException e) {e.printStackTrace();}}

三、代码展示(整体版)

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;import org.apache.commons.io.FileUtils;import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;public class Test {
//指定文件夹String Path = “D:\\...\\xxxx.zip”String Path = “D:\\...\\xxxx.rar”
}
//1.判断文件类型if(path.endsWith(".zip")) {unzip(path);}else if(path.endsWith(".rar")) {unrar(path);}	}//2.解压缩zip格式public static void unzip(String path) {//(1)根据原始路径(字符串),创建源文件(File对象)File sourceFile = new File(path);//(2)根目录String sourceName = sourceFile.getName();File rootDir = new File(sourceFile.getParent()+"\\"+sourceName.substring(0,sourceName.lastIndexOf(".")));//(3)判断根目录是否已经存在if(rootDir.exists()) {//若存在,则删除rootDir.delete();//只能删除空目录//使用commons-io包提供的FileUtils工具类进行删除try {FileUtils.deleteDirectory(rootDir);} catch (IOException e) {e.printStackTrace();}}//(4)创建根目录rootDir.mkdir();//(5)ZipInputStream:用于进行zip格式的压缩输入流try {ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));//(6)遍历压缩包中每个子文件子目录(zipEntry类型的对象)ZipEntry zipEntry = null;while((zipEntry = in.getNextEntry())!=null) {//(7)创建子文件子目录(File对象)File file = new File(rootDir.getPath()+"\\"+zipEntry.getName());//(8)判断是子文件还是子目录(不是子目录就是子文件)if(zipEntry.isDirectory()) {//物理磁盘创建子目录file.mkdir();}else {//物理磁盘创建子文件file.createNewFile();//(9)子文件的写入//读取当前压缩包的子文件,并通过输出流out写入新子文件中try (FileOutputStream out = new FileOutputStream(file)) {byte[] buff = new byte[1024];int len = -1;while((len = in.read(buff))!=-1) {out.write(buff,0,len);}}}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}//3.解压缩rar格式public static void unrar(String path) {//(1)创建解压缩的根目录File rarFile = new File(path);File rootDir = new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));//(2)判断是否存在if(rootDir.exists()) {try {FileUtils.deleteDirectory(rootDir);} catch (IOException e) {e.printStackTrace();}}rootDir.mkdir();//(3)创建Archive对象,用于读取rar压缩文件格式try (Archive archive = new Archive(new FileInputStream(path))){//(4)获取压缩文件所有子目录子文件(FileHeader对象)List<FileHeader> fileheaderList = archive.getFileHeaders();//(5)按照子目录(子文件)名称排序fileheaderList.sort(new Comparator<FileHeader>() {@Overridepublic int compare(FileHeader o1, FileHeader o2) {return o1.getFileName().compareTo(o2.getFileName());}});//(6)遍历子目录子文件for(FileHeader fd : fileheaderList) {File f = new File(rootDir.getPath()+"\\"+fd.getFileName());if(fd.isDirectory()) {//物理磁盘创建子目录f.mkdir();}else {//物理磁盘创建子文件f.createNewFile();//获取压缩包中子文件输入流InputStream in = archive.getInputStream(fd);//复制文件输入流至子文件FileUtils.copyInputStreamToFile(in, f);}}} catch (RarException | IOException e) {e.printStackTrace();}}
}

四、使用场景

    以上提供了两种常见压缩格式(ZIP 和 RAR)文件的解压缩功能。通过判断输入文件的格式(根据文件扩展名),调用相应的解压缩方法(unzip 或 unrar),能够将压缩文件中的内容正确地解压到指定的目录中。

这种功能在很多场景中都非常有用,例如:

  1. 数据处理和分析:当获取到压缩形式的数据时,需要解压缩来获取原始数据进行处理和分析。
  2. 文件传输和存储:在文件传输或存储过程中,压缩可以节省空间和提高传输效率,到达目的地后再解压缩以恢复原始文件结构。
  3. 软件开发:在开发过程中,可能需要处理和整合来自不同来源的压缩文件资源。

        总的来说,这段代码提供了一种灵活且可复用的方式来处理 ZIP 和 RAR 压缩文件的解压缩操作,满足了在各种应用中对压缩文件进行处理的需求。

相关文章:

如何通过 Java 来完成 zip 文件与 rar 文件的解压缩?

目录 一、用到的知识点 二、代码展示(分解版) 三、代码展示(整体版) 一、用到的知识点 1.IO流&#xff1a; Input:输入&#xff0c;通过“输入流”进行文件的读取操作 Output:输出&#xff0c;通过“输出流”进行文件的写入操作 2.文件操作相关&#xff1a; File类&#xff…...

C 语言中的联合(Union)的用途是什么?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&#xff0c;看过的人都说好。 文章目…...

汽车电子助力转向系统研究

汽车电子助力转向系统研究 摘要 电子助力转向系统&#xff08;Electric Power Steering&#xff0c;EPS&#xff09;是一种利用电动机辅助驾驶员进行车辆转向的系统。相比于传统的液压助力转向系统&#xff0c;EPS具有更高的效率、精确性和可控性。本文将详细探讨EPS的工作原理…...

大数据学习之 scala基础(补充)

scala基础&#xff1a; hello world: 写scala可运行文件的注意事项1、如果一个scala文件要运行&#xff0c;class要改成object2、如果是class&#xff0c;就仅单纯代表一个类&#xff0c;如果是object代表的是单例对象3、scala语法中&#xff0c;一句话结束不需要加分号4、sca…...

正向传播和反向传播

正向传播&#xff08;Forward Propagation&#xff09; 正向传播是指将输入数据通过神经网络&#xff0c;计算出预测值的过程。具体步骤如下&#xff1a; 输入层&#xff1a;接受输入数据。隐藏层&#xff1a;每个隐藏层中的神经元接收上一层的输出&#xff0c;进行加权求和&…...

前端文件下载的方式

方式一&#xff1a;a标签直接下载 <a href"链接" >下载</a>一个文件链接&#xff08;一般是服务器上的某个文件&#xff09;&#xff0c;这个链接一般地址栏输入是预览&#xff0c;不是附件下载 如果想改成附件下载&#xff0c;以下两种方式任选一个均…...

视图库对接系列(GA-T 1400)十六、视图库对接系列(本级)通知(订阅回调)

说明 之前我们实现了订阅接口,其中有一个receiveAddr参数, 这个就是对应的回调的地址。一般情况下对应的是同一个服务。 我们推荐使用http://xxx:xxx/VIID/SubscribeNotifications接口文档 SubscribeNotificationList对象对象如下: 文档中是xml,但实际上目前使用的都是jso…...

Python | Leetcode Python题解之第230题二叉搜索树中第K小的元素

题目&#xff1a; 题解&#xff1a; class AVL:"""平衡二叉搜索树&#xff08;AVL树&#xff09;&#xff1a;允许重复值"""class Node:"""平衡二叉搜索树结点"""__slots__ ("val", "parent&quo…...

Python酷库之旅-第三方库Pandas(018)

目录 一、用法精讲 44、pandas.crosstab函数 44-1、语法 44-2、参数 44-3、功能 44-4、返回值 44-5、说明 44-6、用法 44-6-1、数据准备 44-6-2、代码示例 44-6-3、结果输出 45、pandas.cut函数 45-1、语法 45-2、参数 45-3、功能 45-4、返回值 45-5、说明 4…...

九科bit-Worker RPA 内容学习

入门阶段&#xff0c; 花时间学习和记忆细枝末节&#xff0c;可能会反而分散新手去理解核心逻辑的精力&#xff0c;并且不常用的知识也很容易被遗忘。 简介&#xff1a; 什么是RPA&#xff1f; RPA&#xff08;Robotic Process Automation&#xff0c;机器人流程自动化&#x…...

vscode编译环境配置-golang

1. 支持跳转 如果单测函数上方不显示run test | debug test&#xff0c;需要安装Code Debugger&#xff08;因为以前的go Test Explorer不再被维护了&#xff09; 2. 单测 指定单个用例测试 go test -v run TestXXXdlv 调试 需要安装匹配的go版本和delve版本&#xff08;如…...

【JavaEE】网络编程——UDP

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; 文章目录 1.数据报套接字(UDP)1.1特点1.2编码1.2.1DatagramSocket1.2.2DatagramPacket…...

JAVA毕业设计147—基于Java+Springboot的手机维修管理系统(源代码+数据库)

基于JavaSpringboot的手机维修管理系统(源代码数据库)147 一、系统介绍 本项目分为用户、管理员、维修员三种角色 1、用户&#xff1a; 注册、登录、新闻公告、售后申请、申请列表、意见反馈、个人信息、密码修改 2、管理员&#xff1a; 用户管理、用户管理、栏目管理、网…...

力扣第228题“汇总区间”

在本篇文章中&#xff0c;我们将详细解读力扣第228题“汇总区间”。通过学习本篇文章&#xff0c;读者将掌握如何遍历和汇总区间&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述 力扣第228题“汇总区间”描…...

部署大语言模型并对话

在阿里云的https://developer.aliyun.com/adc/scenario/b105013328814fe995c0f091d708d67d 选择函数计算 设置服务器配置 复制公网地址 这个地址不能直接 在返回应用&#xff0c;创建应用LLM 对话页面 Open WebUI 点击下面的创建应用 部署完成后访问域名 打开访问地址...

WebSocket、socket.io-client

WebSocket WebSocket 是一种网络通信协议&#xff0c;它提供了一个在单个长期持久的 TCP 连接上进行全双工&#xff08;full-duplex&#xff09;通信的通道。 WebSocket 允许客户端和服务器之间进行双向的数据交换&#xff0c;这意味着服务器可以主动向客户端推送数据&#x…...

Maven 仓库

在 Maven 世界中&#xff0c;任何一个依赖、插件或者项目构建的输出&#xff0c;都可以称为 构件 。 坐标和依赖是构件在 Maven 世界中的逻辑表示方式&#xff0c;构件的物理表示方式是文件&#xff0c;Maven 通过仓库来统一管理这些文件。 任何一个构件都有一组坐标唯一标识。…...

给后台写了一个优雅的自定义风格的数据日志上报页面

highlight: atelier-cave-dark 查看后台数据日志是非常常见的场景,经常看到后台的小伙伴从服务器日志复制一段json数据字符串,然后找一个JSON工具网页打开,在线JSON格式化校验。有的时候,一些业务需要展示mqtt或者socket的实时信息展示,如果不做任何修改直接展示一串字符…...

【React Native优质开源项目】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…...

Android 自动更新时间的数字时钟 TextClock

TextClock 继承 TextView &#xff0c;使用方法和 TextView 一样。 它专门用于显示数字时钟&#xff0c;可以自定义显示格式。 只要在布局文件里添加&#xff0c;它会自动更新时间&#xff0c;不需要添加刷新逻辑。 布局文件&#xff0c; <?xml version"1.0"…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...

SQL进阶之旅 Day 22:批处理与游标优化

【SQL进阶之旅 Day 22】批处理与游标优化 文章简述&#xff08;300字左右&#xff09; 在数据库开发中&#xff0c;面对大量数据的处理任务时&#xff0c;单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”&#xff0c;深入探讨如何通过批量操作和游标技术提…...

构建Docker镜像的Dockerfile文件详解

文章目录 前言Dockerfile 案例docker build1. 基本构建2. 指定 Dockerfile 路径3. 设置构建时变量4. 不使用缓存5. 删除中间容器6. 拉取最新基础镜像7. 静默输出完整示例 docker runDockerFile 入门syntax指定构造器FROM基础镜像RUN命令注释COPY复制ENV设置环境变量EXPOSE暴露端…...