如何使用Java解压压缩包

本文介绍使用最广泛的zip以及rar两种压缩包的处理方式。先介绍使用jdk本体就可以解压的zip。

zip处理方式

public static void main(String[] args) {
        //字符串中填写你的压缩包路径
        String path = "E:\\Codes\\Java_works\\excise-basic\\src\\javaSE_exise\\javaIO练习\\easyftp-server-1.7.0.10-cn.zip";
        if (path.endsWith(".zip")) {
            unzip(path);
        } else if (path.endsWith(".rar")) {
            unrar(path);
        }
    }

主方法中需要根据后缀名来判断解压的是zip文件还是rar文件

zip文件则调用unzip()方法

方法如下:

public static void unzip(String path) {
        // 根据原始路径(path),创建源文件(File对象)
        File sourceFile = new File(path);

        // 创建根目录
        // 获取文件名
        String name = sourceFile.getName()
                .substring(0, sourceFile.getName().lastIndexOf("."));// 包括了后缀名(但是我们不需要后缀名)
        // 创建解压文件夹目录与压缩文件同目录,所以就要在上级目录开始创建
        File rootDir = new File(sourceFile.getParent() + "\\" + name);
        if (rootDir.exists()) {
            // 存在就删除
            // rootDir.delete();//普通删除如果目录中含有文件或者子目录就无法删除
            try {
                FileUtils.deleteDirectory(rootDir);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 删除后创建文件夹
        rootDir.mkdir();

        // 读压缩文件.zip内的文件 使用ZipInputSream
        try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(path));) {
            // 压缩包中每个子目录或者文件就是ZipEntry对象
            ZipEntry zipEntry = null;
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                System.out.println(zipEntry.getName());
                // 将读到的文件以及文件夹新建在之前存放解压文件的目录下rootDir
                File file = new File(rootDir.getPath() + "\\" + zipEntry.getName());
                // 判断解压的是文件还是文件夹
                if (zipEntry.isDirectory()) {
                    file.mkdir();
                } else {
                    // 创建完文件之后写入内容
                    file.createNewFile();
                    // 使用FIleOutputSream输出当前文件
                    try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
                        byte[] buff = new byte[1024];
                        int len = -1;
                        // 将读到的字节存储在数组中
                        while ((len = zipInputStream.read()) != -1) {
                            fileOutputStream.write(buff, 0, len);
                        }
                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

要点如下

1.getName()方法会获得文件全名包括后缀名,所以在开始创建解压根目录时,需要对获得到的文件名进行截取

2.File类型使用delete()方法只可以删除空文件夹,需要借助commons包的中FileUtils类的deleteDirectory(File file)方法

3.zip文件需要使用ZipInputStream类,使用FileInputStream类实例,因为不管读取什么文件本质上都要使用FileInputStream去读取

4.压缩包中的每个文件或文件夹,都是一个ZipEntry对象,需要对ZipEntry对象进行判断,使用isDirectory()方法,如果为真则说明是一个当前ZipEntry对象是一个文件夹,就需要在解压根目录下创建文件夹,否则说明是文件,将读到的字节存入字符数组使用FileOutputStream中的write(写出的字节数组,从哪里开始,到哪里结束)方法写出。

rar的处理方式

相较于zip,rar处理需要使用第三方的jar包分别为slf4j-api、junrar

main方法写法同上,此处只介绍unrar()方法如何实现

方法如下:

public static void unrar(String path) {
        // 创建解压的源文件的根目录
        File file = new File(path);
        String name = file.getName().substring(0, file.getName().lastIndexOf("."));
        File rootDir = new File(file.getParent() + "\\" + name);
        if (rootDir.exists()) {
            try {
                FileUtils.deleteDirectory(rootDir);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        rootDir.mkdir();

        // 读取rar压缩包内的文件 创建Archive对象
        try (Archive archive = new Archive(new FileInputStream(path))) {
            // 获取压缩文件中的所有子目录子文件FileHeader对象
            List<FileHeader> fileHeadersList = archive.getFileHeaders();
            // 按照子目录子文件名称排序
            fileHeadersList.sort(new Comparator<FileHeader>() {
                // 自定义排序规则
                @Override
                public int compare(FileHeader o1, FileHeader o2) {
                    return o1.getFileName().compareTo(o2.getFileName());
                }
            });

            for (FileHeader fileHeader : fileHeadersList) {
                System.out.println(fileHeader.getFileName());
                File f = new File(rootDir.getPath() + "\\" + fileHeader.getFileName());
                if (fileHeader.isDirectory()) {
                    f.mkdir();
                } else {
                    f.createNewFile();
                    // 读入文件流
                    InputStream inputStream = archive.getInputStream(fileHeader);
                    // 将读入文件的流写在根目录文件对象上
                    FileUtils.copyInputStreamToFile(inputStream, f);
                }
            }
        } catch (RarException | IOException e) {
            e.printStackTrace();
        }

    }

要点如下:

1.Archive 就类似于java自带的ZipInputStream,同样是读取文件自然也需要使用FileInputStream来实例。

2.读取rar中的文件或文件夹实体可以直接使用Archive中getFileHeaders()方法,这种遍历方法深度优先找不到上一级目录,所以我们需要对其进行从排序。此处从写Comparator中的compare方法,自定义排序规则,这里用比较字符串来排序。

3.获得压缩包内实体后,进行遍历,将每个实体实例为File对象,判断是文件夹还是文件,此步骤同上。rar写入数据与zip有所不,使用Archive获取输入流之后,不用像zip一样边读边写,而是直接将文件输入流复制到文件对象上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值