如何通过 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
),能够将压缩文件中的内容正确地解压到指定的目录中。
这种功能在很多场景中都非常有用,例如:
- 数据处理和分析:当获取到压缩形式的数据时,需要解压缩来获取原始数据进行处理和分析。
- 文件传输和存储:在文件传输或存储过程中,压缩可以节省空间和提高传输效率,到达目的地后再解压缩以恢复原始文件结构。
- 软件开发:在开发过程中,可能需要处理和整合来自不同来源的压缩文件资源。
总的来说,这段代码提供了一种灵活且可复用的方式来处理 ZIP 和 RAR 压缩文件的解压缩操作,满足了在各种应用中对压缩文件进行处理的需求。
相关文章:
如何通过 Java 来完成 zip 文件与 rar 文件的解压缩?
目录 一、用到的知识点 二、代码展示(分解版) 三、代码展示(整体版) 一、用到的知识点 1.IO流: Input:输入,通过“输入流”进行文件的读取操作 Output:输出,通过“输出流”进行文件的写入操作 2.文件操作相关: File类ÿ…...

C 语言中的联合(Union)的用途是什么?
🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会! 📙C 语言百万年薪修炼课程 通俗易懂,深入浅出,匠心打磨,死磕细节,6年迭代,看过的人都说好。 文章目…...
汽车电子助力转向系统研究
汽车电子助力转向系统研究 摘要 电子助力转向系统(Electric Power Steering,EPS)是一种利用电动机辅助驾驶员进行车辆转向的系统。相比于传统的液压助力转向系统,EPS具有更高的效率、精确性和可控性。本文将详细探讨EPS的工作原理…...
大数据学习之 scala基础(补充)
scala基础: hello world: 写scala可运行文件的注意事项1、如果一个scala文件要运行,class要改成object2、如果是class,就仅单纯代表一个类,如果是object代表的是单例对象3、scala语法中,一句话结束不需要加分号4、sca…...
正向传播和反向传播
正向传播(Forward Propagation) 正向传播是指将输入数据通过神经网络,计算出预测值的过程。具体步骤如下: 输入层:接受输入数据。隐藏层:每个隐藏层中的神经元接收上一层的输出,进行加权求和&…...
前端文件下载的方式
方式一:a标签直接下载 <a href"链接" >下载</a>一个文件链接(一般是服务器上的某个文件),这个链接一般地址栏输入是预览,不是附件下载 如果想改成附件下载,以下两种方式任选一个均…...

视图库对接系列(GA-T 1400)十六、视图库对接系列(本级)通知(订阅回调)
说明 之前我们实现了订阅接口,其中有一个receiveAddr参数, 这个就是对应的回调的地址。一般情况下对应的是同一个服务。 我们推荐使用http://xxx:xxx/VIID/SubscribeNotifications接口文档 SubscribeNotificationList对象对象如下: 文档中是xml,但实际上目前使用的都是jso…...

Python | Leetcode Python题解之第230题二叉搜索树中第K小的元素
题目: 题解: class AVL:"""平衡二叉搜索树(AVL树):允许重复值"""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 内容学习
入门阶段, 花时间学习和记忆细枝末节,可能会反而分散新手去理解核心逻辑的精力,并且不常用的知识也很容易被遗忘。 简介: 什么是RPA? RPA(Robotic Process Automation,机器人流程自动化&#x…...

vscode编译环境配置-golang
1. 支持跳转 如果单测函数上方不显示run test | debug test,需要安装Code Debugger(因为以前的go Test Explorer不再被维护了) 2. 单测 指定单个用例测试 go test -v run TestXXXdlv 调试 需要安装匹配的go版本和delve版本(如…...

【JavaEE】网络编程——UDP
🤡🤡🤡个人主页🤡🤡🤡 🤡🤡🤡JavaEE专栏🤡🤡🤡 文章目录 1.数据报套接字(UDP)1.1特点1.2编码1.2.1DatagramSocket1.2.2DatagramPacket…...

JAVA毕业设计147—基于Java+Springboot的手机维修管理系统(源代码+数据库)
基于JavaSpringboot的手机维修管理系统(源代码数据库)147 一、系统介绍 本项目分为用户、管理员、维修员三种角色 1、用户: 注册、登录、新闻公告、售后申请、申请列表、意见反馈、个人信息、密码修改 2、管理员: 用户管理、用户管理、栏目管理、网…...
力扣第228题“汇总区间”
在本篇文章中,我们将详细解读力扣第228题“汇总区间”。通过学习本篇文章,读者将掌握如何遍历和汇总区间,并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释,以便于理解。 问题描述 力扣第228题“汇总区间”描…...

部署大语言模型并对话
在阿里云的https://developer.aliyun.com/adc/scenario/b105013328814fe995c0f091d708d67d 选择函数计算 设置服务器配置 复制公网地址 这个地址不能直接 在返回应用,创建应用LLM 对话页面 Open WebUI 点击下面的创建应用 部署完成后访问域名 打开访问地址...
WebSocket、socket.io-client
WebSocket WebSocket 是一种网络通信协议,它提供了一个在单个长期持久的 TCP 连接上进行全双工(full-duplex)通信的通道。 WebSocket 允许客户端和服务器之间进行双向的数据交换,这意味着服务器可以主动向客户端推送数据&#x…...
Maven 仓库
在 Maven 世界中,任何一个依赖、插件或者项目构建的输出,都可以称为 构件 。 坐标和依赖是构件在 Maven 世界中的逻辑表示方式,构件的物理表示方式是文件,Maven 通过仓库来统一管理这些文件。 任何一个构件都有一组坐标唯一标识。…...

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

【React Native优质开源项目】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...

Android 自动更新时间的数字时钟 TextClock
TextClock 继承 TextView ,使用方法和 TextView 一样。 它专门用于显示数字时钟,可以自定义显示格式。 只要在布局文件里添加,它会自动更新时间,不需要添加刷新逻辑。 布局文件, <?xml version"1.0"…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...