Java操作压缩包解压过程详解
在Java开发中,处理压缩文件(如ZIP、RAR等)是一项常见的任务,特别是在需要处理大量数据、备份或分发应用程序时。Java标准库(Java SE)提供了对ZIP格式的原生支持,通过java.util.zip
包中的类来实现压缩和解压功能。本文将重点介绍如何使用Java来解压ZIP或RAR压缩包。
一、解压压缩包
解压压缩包,借助ZipInputStream类,可以读取到压缩包中的每一个文件,然后根据读取到的文件属性,写入到相应路径下即可。对于解压压缩包中是文件树的结构,每读取到一个文件后,如果是多层路径下的文件,需要先创建父目录,再写入文件流。
1.zip解压代码实现
// 解压zip格式 public static void unzip(String path){ // 根据原始路径(字符串),创建源文件(File对象) File sourceFile = new File(path); // 根目录 String sourceFileName = sourceFile.getName(); File rootDir = new File(sourceFile.getParent()+"\\"+sourceFileName.substring(0,sourceFileName.lastIndexOf("."))); // 判断根目录是否已经存在 if(rootDir.exists()){ // 如果存在,则删除 // rootDir.delete(); // 仅能删除空目录 // 使用commons-io包提供的FileUtils工具类进行删除 try { FileUtils.deleteDirectory(rootDir); } catch (IOException e) { e.printStackTrace(); } } // 创建根目录 rootDir.mkdirs(); // System.out.println(rootDir); // ZipInputStream:用于进行zip格式的压缩文件输入流 try (ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile))) { // 遍历压缩包中的每个子目录或子文件(ZipEntry类型的对象) ZipEntry zipEntry = null; while((zipEntry = in.getNextEntry()) != null){ // System.out.println(zipEntry.getName()); // 创建子目录或子文件(File对象) // F:\Software\IDEA\Projects\test\easyftp-server-1.7.0.10-cn File file = new File(rootDir.getPath()+"\\"+zipEntry.getName()); if(zipEntry.isDirectory()){ // 物理磁盘创建子目录 file.mkdirs(); }else{ // 物理磁盘创建子文件 file.createNewFile(); // 读取当前压缩包中的子文件,并通过输出流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 (IOException e) { e.printStackTrace(); } }
2.rar解压代码实现
// 解压缩rar格式 private static void unrar(String path) { // 1.创建解压缩的根目录 File rarFile = new File(path); // File rootDir = new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf("."))); String rarFileName = rarFile.getName(); File rootDir = new File(rarFile.getParent()+"\\"+rarFileName.substring(0,rarFileName.lastIndexOf("."))); if(rootDir.exists()){ try { FileUtils.deleteDirectory(rootDir); } catch (IOException e) { e.printStackTrace(); } } rootDir.mkdirs(); // 创建Archive对象,用于读取rar压缩文件格式 try(Archive archive = new Archive(new FileInputStream(path))) { // 读取压缩文件中的所有子目录或子文件(FileHeader对象) List<FileHeader> fileHeaderList = archive.getFileHeaders(); // 按照子目录(子文件)名来排序 fileHeaderList.sort(new Comparator<FileHeader>() { @Override public int compare(FileHeader o1, FileHeader o2) { return o1.getFileName().compareTo(o2.getFileName()); } }); // 遍历子目录和子文件 for (FileHeader fd:fileHeaderList) { System.out.println(fd.getFileName()); File f = new File(rootDir.getPath()+"\\"+fd.getFileName()); if(fd.isDirectory()){ // 创建新子目录 f.mkdirs(); }else{ // 创建新子文件 f.createNewFile(); // 获取压缩包中的子文件输出流 InputStream in = archive.getInputStream(fd); // 复制文件输入流至新子文件 FileUtils.copyInputStreamToFile(in,f); } } } catch (RarException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
3.调用解压方法
最后,在main
方法或任何其他适当的位置调用unzip
方法,传入ZIP或RAR文件的路径和解压到的目标。
import com.github.junrar.Archive; import com.github.junrar.exception.RarException; import com.github.junrar.rarfile.FileHeader; import org.apache.commons.io.FileUtils; import java.io.*; import java.util.Comparator; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public static void main(String[] args) { // String path = "F:\\Software\\IDEA\\Projects\\test\\easyftp-server-1.7.0.10-cn.zip"; String path = "F:\\Software\\IDEA\\Projects\\test\\实验案例.rar"; if(path.endsWith(".zip")) { unzip(path); } else if(path.endsWith(".rar")){ unrar(path); } }
二、注意事项
- 文件路径处理:在解压时,注意正确处理ZIP文件中的文件路径,以避免安全风险(如路径遍历攻击)。
- 异常处理:在解压过程中,可能会遇到文件读取错误、写入错误或权限问题,应妥善处理这些异常。
- 性能优化:对于大型ZIP文件,考虑使用更高效的IO操作和流控制来优化解压速度。
- 压缩用到的JAR包:需要使用第三方库,如commons-io包。
三、总结
- 在解压缩文件过程中,主要是对流的读取操作,注意进行异常处理,以及关闭流。
- 解压缩文件时,注意空文件夹的处理。
到此这篇关于Java操作压缩包解压过程详解的文章就介绍到这了,更多相关Java压缩包解压内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
ArrayList foreach循环增添删除导致ConcurrentModificationException解决分
这篇文章主要为大家介绍了ArrayList foreach循环增添删除导致ConcurrentModificationException解决分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>2023-12-12详解Java基础篇--面向对象1(构造方法,static、this关键字)
这篇文章主要介绍了Java基础篇--面向对象1(构造方法,static、this关键字),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-04-04springboot整合shardingsphere和seata实现分布式事务的实践
本文主要介绍了springboot整合shardingsphere和seata实现分布式事务的实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2022-07-07
最新评论