如何通过 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"…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
