首页 > 编程语言 >【Java】压缩包解压实现过程

【Java】压缩包解压实现过程

时间:2024-07-14 12:27:10浏览次数:16  
标签:解压 文件 Java rootDir File path new 压缩包

       在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);
        }
    }

    

二、注意事项

  1. 文件路径处理:在解压时,注意正确处理ZIP文件中的文件路径,以避免安全风险(如路径遍历攻击)。
  2. 异常处理:在解压过程中,可能会遇到文件读取错误、写入错误或权限问题,应妥善处理这些异常。
  3. 性能优化:对于大型ZIP文件,考虑使用更高效的IO操作和流控制来优化解压速度。
  4. 压缩用到的JAR包:需要使用第三方库,如commons-io包。

三、总结

  • 在解压缩文件过程中,主要是对流的读取操作,注意进行异常处理,以及关闭流。
  • 解压缩文件时,注意空文件夹的处理。

标签:解压,文件,Java,rootDir,File,path,new,压缩包
From: https://blog.csdn.net/weixin_71491685/article/details/140359449

相关文章

  • [0079]基于JAVA的专线物流智慧管理系统的设计与实现
    毕业设计(论文)开题报告表姓名学院专业班级题目基于JAVA的专线物流智慧管理系统的设计与实现指导老师(一)选题的背景和意义随着信息技术的发展和互联网的普及,物流行业正面临着一场深刻的变革。传统的物流管理模式已经无法满足现代企业的需求,因此开发一......
  • Java NIO SocketChannel
    JavaNIOSocketChannel用于将通道与TCP(传输控制协议)网络套接字连接。它相当于网络编程中使用的Java网络套接字(Socket)。JavaNIO中有两种可用于创建SocketChannel的方法:当传入连接到达ServerSocketChannel时,可以创建它。打开一个SocketChannel,并在网络上与服务器连接。......
  • Java NIO管道
    JavaNIO管道用于在两个线程之间建立单向数据连接。它有一个槽通道和源通道。数据正在写入槽通道,然后可以从源通道读取该数据。在JavaNIO中,包java.nio.channel.pipe用于按顺序读取和写入数据。管道用于确保数据必须以写入管道的相同顺序读取。下面来看看管道工作原理的示意......
  • 【java深入学习第5章】Spring Boot 中统一功能的实现与处理
    SpringBoot统一功能处理在开发Web应用程序时,为了提高代码的可维护性和可扩展性,我们通常会采用一些统一的功能处理方式。本文将介绍如何在SpringBoot中实现统一的数据返回格式、异常处理和功能处理,并通过一个图书管理系统的案例来演示这些功能的实现。一、统一数据返回格......
  • 【java深入学习第6章】Spring事件监听机制详解
    在Spring框架中,事件监听机制是一个强大且灵活的功能,允许我们在应用程序中发布和监听事件。这种机制可以帮助我们实现松耦合的设计,使得不同模块之间的通信更加灵活和可维护。本文将详细介绍Spring的事件监听机制,并通过代码示例展示如何使用这一功能。1.什么是Spring事件监听机制?......
  • java InputStream read使用及读取数据注意
    publicabstractintread()throwsIOException;从输入流中读取下一个字节的数据。值字节以int的形式返回,范围在0-255之间。如果由于到达流的末尾而没有字节可用,则返回值-1。此方法会一直阻塞,直到输入数据可用、检测到流结束或抛出异常为止。 publicintread(byteb[],i......
  • 面试篇-Java-1+锁+AQS+死锁
    文章目录前言一、并发编程中你都用过哪些锁1.1Synchronized【对象锁】1.1.1Synchronized的使用1.1.2你知道Synchronized的原理吗1.1.2.1你知道monitor的结构1.1.3Synchronized的实现原理1.1.3你知道Synchronized锁的升级吗1.1.3.1你知道对象头的内存结构和对......
  • 【java深入学习第4章】精通 Java 微服务:Spring Boot 与 Spring Cloud 的核心技术与设
    在现代软件开发中,微服务架构因其灵活性和可扩展性而备受青睐。本文将探讨Java微服务架构中的关键技术和设计原则,并通过SpringBoot和SpringCloud提供代码示例,展示如何构建一个简单的微服务应用。关键技术和设计原则服务拆分:将单体应用拆分为多个独立的微服务,每个服务负责特定......
  • 【java深入学习第2章】Spring Boot 结合 Screw:高效生成数据库设计文档之道
    在开发过程中,数据库设计文档是非常重要的,它可以帮助开发者理解数据库结构,方便后续的维护和扩展。手动编写数据库设计文档不仅耗时,而且容易出错。幸运的是,可以使用SpringBoot和Screw来自动生成数据库设计文档。什么是Screw?Screw是一个开源的数据库文档生成工具,它可以根据数据库......
  • 【java深入学习第3章】通过 Spring AOP 完成参数的加解密
    在现代应用中,数据的安全性越来越受到重视。为了保护敏感数据,我们常常需要对数据进行加密和解密。在这篇博客中,我将展示如何使用SpringAOP(面向切面编程)来实现对方法参数的加解密。什么是SpringAOP?SpringAOP是Spring框架中的一个模块,它提供了面向切面编程的功能。AOP允许我们将......