Java操作压缩包解压过程详解

 更新时间:2024年10月03日 11:37:17   作者:Satan712  
这篇文章主要介绍了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压缩包解压内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于Java中ArrayList的源码分析

    关于Java中ArrayList的源码分析

    这篇文章主要从源码角度带大家深入了解一下Java中ArrayList的构造方法和属性等知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-05-05
  • 使用socket进行服务端与客户端传文件的方法

    使用socket进行服务端与客户端传文件的方法

    这篇文章主要介绍了使用socket进行服务端与客户端传文件的方法,需要的朋友可以参考下
    2017-08-08
  • ArrayList foreach循环增添删除导致ConcurrentModificationException解决分析

    ArrayList foreach循环增添删除导致ConcurrentModificationException解决分

    这篇文章主要为大家介绍了ArrayList foreach循环增添删除导致ConcurrentModificationException解决分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2023-12-12
  • async-excel实现多sheet异步导出方法详解

    async-excel实现多sheet异步导出方法详解

    这篇文章主要介绍了async-excel实现多sheet异步导出方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • Java递归寻路实现,你真的理解了吗

    Java递归寻路实现,你真的理解了吗

    递归就是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,需要的朋友可以参考下
    2021-08-08
  • SpringBoot如何优雅实现接口参数验证

    SpringBoot如何优雅实现接口参数验证

    为了保证参数的正确性,我们需要使用参数验证机制,来检测并处理传入的参数格式是否符合规范,所以本文就来和大家聊聊如何优雅实现接口参数验证吧
    2023-08-08
  • 详解Java基础篇--面向对象1(构造方法,static、this关键字)

    详解Java基础篇--面向对象1(构造方法,static、this关键字)

    这篇文章主要介绍了Java基础篇--面向对象1(构造方法,static、this关键字),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Java NIO Buffer过程详解

    Java NIO Buffer过程详解

    这篇文章主要介绍了Java NIO Buffer过程详解,缓冲区在java nio中负责数据的存储。缓冲区就是数组。用于存储不同数据类型的数据。,需要的朋友可以参考下
    2019-06-06
  • 详解Spring通过@Value注解注入属性的几种方式

    详解Spring通过@Value注解注入属性的几种方式

    本篇文章主要介绍了详解Spring通过@Value注解注入属性的几种方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • springboot整合shardingsphere和seata实现分布式事务的实践

    springboot整合shardingsphere和seata实现分布式事务的实践

    本文主要介绍了springboot整合shardingsphere和seata实现分布式事务的实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论