Apache Commons Compress介绍-Zip压缩解压

宇文卓
2023-12-01

#Apache Commons Compress介绍-Zip压缩解压

简述

  • Apache Commons Compress 官网:http://commons.apache.org/proper/commons-compress/index.html
  • Apache Commons Compress 库定义了一个用于处理 ar,cpio,Unix 转储,tar,zip,gzip,XZ,Pack200,bzip2、7z,arj,lzma,snappy,DEFLATE,lz4,Brotli,Zstandard,DEFLATE64 和 Z 文件的 API 。当前 Compress 版本是 1.21,并且需要 Java 7 及以上支持。

实现

       <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.21</version>
        </dependency>
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;

/**
 * @description:
 * @author: jiazefeng
 * @date: Created in 2022/06/26 上午 10:20
 * @version:
 * @modified By:
 */
public class ZipUtilApache {
    /**
     * 压缩文件
     *
     * @param sourceFiles 原文件数据集
     * @param zipFile     压缩后的文件地址
     * @throws Exception
     */
    public static String doZip(List<String> sourceFiles, String zipFile) {
        File zip = new File(zipFile);
        if (!zip.getParentFile().exists()) {
            zip.getParentFile().mkdirs();
        }
        try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(zip)) {
            //ZipArchiveOutputStream(File file) :根据文件构建压缩输出流,将源文件压缩到此文件.
            //setUseZip64(final Zip64Mode mode):是否使用 Zip64 扩展。
            // Zip64Mode 枚举有 3 个值:Always:对所有条目使用 Zip64 扩展、Never:不对任何条目使用Zip64扩展、AsNeeded:对需要的所有条目使用Zip64扩展
            outputStream.setUseZip64(Zip64Mode.AsNeeded);
            for (String sourceFile : sourceFiles) {
                File file = new File(sourceFile);
                //将每个源文件用 ZipArchiveEntry 实体封装,然后添加到压缩文件中. 这样将来解压后里面的文件名称还是保持一致.
                ZipArchiveEntry entry = new ZipArchiveEntry(file.getName());
                // 可以设置压缩等级
                outputStream.setLevel(5);
                // 可以设置压缩算法,当前支持ZipEntry.DEFLATED和ZipEntry.STORED两种
                outputStream.setMethod(ZipEntry.DEFLATED);
                // 也可以为每个文件设置压缩算法
                entry.setMethod(ZipEntry.DEFLATED);
                // 在zip中创建一个文件
                outputStream.putArchiveEntry(entry);
                try (InputStream inputStream = new FileInputStream(file)) {
                    byte[] buffer = new byte[1024 * 5];
                    int length = -1;//每次读取的字节大小。
                    while ((length = inputStream.read(buffer)) != -1) {
                        //把缓冲区的字节写入到 ZipArchiveEntry
                        outputStream.write(buffer, 0, length);
                    }
                    // 完成一个文件的写入
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
            outputStream.closeArchiveEntry(); //写入此条目的所有必要数据。如果条目未压缩或压缩后的大小超过4 GB 则抛出异常
            outputStream.finish();//压缩结束.
        } catch (Exception e) {
            return null;
        }
        return zipFile;
    }

    /**
     * 解压zip
     *
     * @param zipPath      zip文件路径 必传
     * @param saveFilePath 如果为空那么解压到zipPath的当前目录,不为空解压到指定目录
     */
    public static void unZip(String zipPath, String saveFilePath) {
        try {
            //保存解压文件目录
            if (StringUtils.isNotBlank(saveFilePath)) {
                saveFilePath = new File(saveFilePath) + File.separator;
            } else {
                saveFilePath = new File(zipPath).getParent() + File.separator;
            }
            File zip = new File(zipPath);
            ZipFile zipFile = new ZipFile(zip);
            byte[] buffer = new byte[4096];
            ZipArchiveEntry entry;
            Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); // 获取全部文件的迭代器
            while (entries.hasMoreElements()) {
                entry = entries.nextElement();
                if (entry.isDirectory()) {
                    continue;
                }

                File outputFile = new File(saveFilePath + entry.getName());

                if (!outputFile.getParentFile().exists()) {
                    outputFile.getParentFile().mkdirs();
                }

                try (InputStream inputStream = zipFile.getInputStream(entry);
                     FileOutputStream fos = new FileOutputStream(outputFile)) {
                    while (inputStream.read(buffer) > 0) {
                        fos.write(buffer);
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
@SpringBootTest
public class ZipUtilTest {

    @Test
    public void testDoZip() {
        List<String> fileList = new ArrayList<>();
        fileList.add("D:\\Java 最常见 200+ 面试题全解析:面试必备.pdf");
        fileList.add("D:\\2019年一些前端的面试题(含答案) - 简书.pdf");
        fileList.add("D:\\前端面试题(2019篇)附答案-黑马程序员技术交流社区.pdf");
        fileList.add("D:\\尚飞家长会《我们不一样,我们都很棒》2019.11.11.pptx");
        fileList.add("D:\\Java笔试题.docx");
        ZipUtilApache.doZip(fileList, "D:\\zip\\测试ZIP压缩.zip");
    }

    @Test
    public void testUnZip(){
        ZipUtilApache.unZip("D:\\zip\\手动压缩测试.zip","D:\\zip\\out");
    }
}
 类似资料: