如何通过 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 压缩文件的解压缩操作,满足了在各种应用中对压缩文件进行处理的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/43995.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Point Cloud Library (PCL) for Python - pclpy 安装指南 (2)

Point Cloud Library (PCL) for Python - pclpy 安装指南 (1) 导入库 from pclpy import pcl import numpy as np导入pclpy库中的pcl模块&#xff0c;用于处理点云数据。numpy库用于处理数值数据。 读取点云 cloud pcl.PointCloud.PointXYZRGB() pcl.io.loadPCDFile(F:\\bunn…

2024年西安铁一中集训DAY1---- 杂题选讲

文章目录 牛客练习赛125 E 联谊活动&#xff08;枚举&#xff0c;分讨&#xff09;牛客练习赛125 F 玻璃弹珠&#xff08;类莫队&#xff0c;离线询问&#xff0c;数据结构&#xff09;2024ccpc长春邀请赛 D Parallel Lines&#xff08;随机化&#xff09;2024ccpc长春邀请赛 E…

STM32智能健康监测系统教程

目录 引言环境准备智能健康监测系统基础代码实现&#xff1a;实现智能健康监测系统 4.1 数据采集模块 4.2 数据处理与分析模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;健康监测与优化问题解决方案与优化收尾与总结 1. 引言 智能健康监测系统通…

k8s 容器环境下的镜像如何转换为docker 使用

在无法连接registry 的环境中&#xff0c;想要把 crictl 中的镜像给docker 使用&#xff0c;应该怎么处理&#xff1f; 其实容器镜像是通用的&#xff0c;crictl 和ctr 以及docker 镜像是可以互相使用的&#xff0c;因为docker 在1.10版本之后遵从了OCI。所以crictl 环境下的镜…

Android Studio 的Gradle下载慢,Gradle切换下载源

看图 下面的文字地址因为转义符号的问题&#xff0c;https后面少了一个斜杠看图片进行补充&#xff0c;直接复制不知道能不能用 distributionUrlhttps://mirrors.cloud.tencent.com/gradle/gradle-8.7-bin.zip

浪潮服务器内存物理插槽位置

浪潮服务器内存物理插槽位置 如下图所示

Doze和AppStandby白名单配置方法和说明

机制 配置路径 配置案例 说明 影响机制 调试命令 Doze /platform/frameworks/base /data/etc/platform.xml allow-in-power-save 【系统应用Doze白名单配置】 Doze\Job\AppStandby\Alarm\WakeLock\Sync 查看Doze白名单:adb shell dumpsys deviceidle 添加Doze白名单…

漏洞挖掘之信息搜集(一)

本篇文章只从信息搜集的步骤整理 一、选好你要挖掘的src 这一点一定要明确,定好一个,然后下定决心一定要挖到一个高危 常见src总结: 360众测(需要考核) 漏洞盒子(还可以,审核很慢)----基本无要求 补天:有钱,但要求高,百度收录占比权重大于等于1或者或者谷歌权…

前端进阶全栈计划:Java基础语法

前言 本教程旨在帮助初学者系统地掌握Java的基础知识。我们将从Java的基本语法开始&#xff0c;逐步深入到面向对象编程、异常处理、多线程编程等核心概念。无论你是编程新手&#xff0c;还是希望夯实基础的开发者&#xff0c;这份指南都将带你走进Java的世界&#xff0c;打下坚…

昇思MindSpore学习笔记6-06计算机视觉--Vision Transormer图像分类

摘要&#xff1a; 记录MindSpore AI框架使用ViT模型在ImageNet图像数据分类上进行训练、验证、推理的过程和方法。包括环境准备、下载数据集、数据集加载、模型解析与构建、模型训练与推理等。 一、概念 1. ViT模型 Vision Transformer 自注意结构模型 Self-Attention Tran…

MySQL(基础篇)

DDL (Data Definition Language) 数据定义语言&#xff0c;用来定义数据库对象(数据库&#xff0c;表&#xff0c; 字段) DML (Data Manipulation Languag) 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改 DQL (Data Query Language) 数据查询语言&#xff0c;用…

前缀,中缀,后缀表达式

前缀表达式 前缀表达式&#xff08;也称为波兰式&#xff09;是一种将运算符放在操作数之前的表示数学表达式的方法。在前缀表达式中&#xff0c;操作符出现在它们所操作的操作数之前。 例如&#xff0c;将中缀表达式5 3转换为前缀表达式&#xff0c;可以写成 5 3。在这个例…

9 个让 Python 性能更高的小技巧,你掌握了吗?

我们经常听到 “Python 太慢了”&#xff0c;“Python 性能不行”这样的观点。但是&#xff0c;只要掌握一些编程技巧&#xff0c;就能大幅提升 Python 的运行速度。 今天就让我们一起来看下让 Python 性能更高的 9 个小技巧 python学习资料分享&#xff08;无偿&#xff09;…

数据(图像)增广

一、数据增强 1、增加一个已有数据集&#xff0c;使得有更多的多样性&#xff0c;比如加入不同的背景噪音、改变图片的颜色和形状。 2、增强数据是在线生成的 3、增强类型&#xff1a; &#xff08;1&#xff09;翻转 &#xff08;2&#xff09;切割 &#xff08;3&#xf…

金龙鱼:只是躺枪?

中储粮罐车运输油罐混用事件持续发酵&#xff0c;食用油板块集体躺枪。 消费者愤怒的火&#xff0c;怕是会让食用油企们一点就着。 今天&#xff0c;我们聊聊“油”茅——金龙鱼。 一边是业内人士指出&#xff0c;油罐混用的现象普遍存在&#xff0c;另一边是金龙鱼回应称&am…

2972.力扣每日一题7/11 Java(击败100%)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 解题思路 解题方法 时间复杂度 空间复杂度 Code 解题思路 该问…

RISC-V主要指令集介绍及规则

推荐资料 RISC-V Reader / RISC-V开放架构设计之道&#xff0c;适合新手阅读。 概述 RISC-V的模块化到底是如何实现的呢&#xff1f; 核心部分&#xff1a;RV32I&#xff0c;代表32位字长的整型指令集&#xff08;Integer&#xff09;&#xff0c;包含了许多整型指令如load…

在C++项目中添加录像功能:从摄像头捕获到视频文件的保存

在C项目中添加录像功能&#xff1a;从摄像头捕获到视频文件的保存 在这篇博客中&#xff0c;我们将介绍如何在一个现有的C项目中添加录像功能&#xff0c;具体包括如何从摄像头捕获图像并将其保存为视频文件。我们将使用OpenCV库来处理图像捕获和视频写入。 目录 引言准备工…

Python学习笔记35:进阶篇(二十四)pygame的使用之音频文件播放

前言 基础模块的知识通过这么长时间的学习已经有所了解&#xff0c;更加深入的话需要通过完成各种项目&#xff0c;在这个过程中逐渐学习&#xff0c;成长。 我们的下一步目标是完成python crash course中的外星人入侵项目&#xff0c;这是一个2D游戏项目。在这之前&#xff…

元组列表之案例

1.列表推导式 基本语法&#xff1a; [表达式 for语句1 if 语句1 for语句2 if语句2 ........ ] 1.零到九的平方列表 a [i*i for i in range(10)] print(a) 2.for 循环前面加if else #如果是偶数乘以2&#xff0c;如果是奇数直接输出 a [i*2 if i%2 0 else i for i in ran…