JAVA实现压缩解压文件

1、源码运行前准备好文件夹

2、源码

package com.els.modules.inquiry.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.util.Arrays;
import java.util.Objects;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class xc {
    public static void main(String[] args) {
        // 测试压缩和解压缩单文件ZIP
        // 被压缩的单文件
        File inputFile = new File("C:\\Users\\HLT\\Desktop\\cs\\cs.docx");
        // 压缩文件保存ZIP文件路径名称
        File zipFile = new File("C:\\Users\\HLT\\Desktop\\cs\\cs.zip");
        //  解压缩ZIP保存路径
        File unzipFile = new File("C:\\Users\\HLT\\Desktop\\cs\\unzip");
        long start = System.currentTimeMillis();
        // 压缩文件
        zipCompress(inputFile, zipFile);
        long end = System.currentTimeMillis();
        System.out.println("ZIP-压缩单文件耗时:" + (end - start) + "毫秒");
        start = System.currentTimeMillis();
        zipDecompress(zipFile, unzipFile);
        end = System.currentTimeMillis();
        System.out.println("ZIP-解压缩单文件耗时:" + (end - start) + "毫秒");




        // 单文件夹多文件压缩和解压缩测试
        // 被压缩的文件夹
        File inputFiles = new File("C:\\Users\\HLT\\Desktop\\cs\\xc");
        // 压缩文件保存ZIP文件路径名称
        File zipFiles = new File("C:\\Users\\HLT\\Desktop\\cs\\xy\\xy.zip");
        //  解压缩ZIP保存路径
        File unzipFiles = new File("C:\\Users\\HLT\\Desktop\\cs\\xy\\xyUnzip");
        start = System.currentTimeMillis();
        // 压缩文件
        zipCompress(inputFiles, zipFiles);
        end = System.currentTimeMillis();
        System.out.println("ZIP - 多文件压缩耗时:" + (end - start) + "毫秒");
        start = System.currentTimeMillis();
        zipDecompress(zipFiles, unzipFiles);
        end = System.currentTimeMillis();
        System.out.println("ZIP - 多文件解压缩耗时:" + (end - start) + "毫秒");
    }

    /**
     * 压缩文件(支持单个文件和单个文件夹)
     * @param sourceFile 被压缩文件/文件夹
     * @param zipFile Zip文件
     */
    public static void zipCompress(File sourceFile, File zipFile) {
        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
            // 设置压缩方法
            zos.setMethod(ZipOutputStream.DEFLATED);
            zos.setLevel(Deflater.BEST_COMPRESSION); // 默认为-1,压缩级别,1速度快,效率低,9 速度满,效率高
            // zos.setLevel(Deflater.BEST_SPEED);
            zos.setComment("zip文件说明");
            // 处理文件夹
            if (sourceFile.exists() && sourceFile.isDirectory() && Objects.nonNull(sourceFile.listFiles())){
                Arrays.stream(Objects.requireNonNull(sourceFile.listFiles())).forEach(file -> {
                    addZipFile(file, zos);
                });
            }else{
                addZipFile(sourceFile, zos);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 向ZIP中添加文件
     * @param file 源文件
     * @param zos zip输出流
     */
    private static void addZipFile(File file, ZipOutputStream zos){
        if (!file.exists() || file.isDirectory()){
            throw new RuntimeException("文件不存在或该文件为文件夹,请检查");
        }
        try {
            // 读入文件
            FileInputStream fis = new FileInputStream(file);
            // 创建压缩对象并设置一些属性
            ZipEntry entry = new ZipEntry(file.getName());
            entry.setMethod(ZipEntry.DEFLATED); // 压缩方法默认为DEFLATED
            // entry.setMethod(ZipEntry.STORED); // STORED(不压缩)。当使用STORED压缩方法时,需要设置未压缩的数据大小和CRC-32校验和,否则压缩和解压缩时会出现错误。
            entry.setSize(file.length()); // 设置未压缩的数据大小,这里设置的是文件大小
            // 计算 CRC-32 校验码
            // byte[] data = Files.readAllBytes(file.toPath());
            // CRC32 crc = new CRC32();
            // crc.update(data);
            // entry.setCrc(crc.getValue()); // 设置CRC-32校验和,用于保证压缩后的数据完整性,尽量别手动设置,可以通过CRC-32计算
            entry.setCompressedSize(file.length()); // 设置压缩后的数据大小,这里设置的是使用DEFLATED方法压缩后的数据大小
            entry.setExtra(new byte[]{}); // 设置额外的数据,这里设置为空
            entry.setComment("file comment"); // 设置ZipEntry的注释,即文件说明
            entry.setCreationTime(FileTime.from(Instant.now())); // 设置文件的创建时间
            entry.setLastAccessTime(FileTime.from(Instant.now())); // 设置文件的最后访问时间
            entry.setLastModifiedTime(FileTime.from(Instant.now())); // 设置文件的最后修改时间。
            // 向ZIP输出流中添加一个ZIP实体,构造方法中的name参数指定文件在ZIP包中的文件名
            zos.putNextEntry(entry);
            // 向ZIP实体中写入内容
            byte[] buf = new byte[1024];
            int len;
            while ((len = fis.read(buf)) > 0) {
                zos.write(buf, 0, len);
            }
            // 关闭ZipEntry
            zos.closeEntry();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 解压缩ZIP文件
     * @param zipFile ZIP文件
     * @param destDir 目标路径
     */
    public static void zipDecompress(File zipFile, File destDir) {
        byte[] buffer = new byte[1024];
        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
            ZipEntry entry = zis.getNextEntry();
            while (entry != null) {
                File file = new File(destDir, entry.getName());
                if (entry.isDirectory()) {
                    file.mkdirs();
                } else {
                    File parent = file.getParentFile();
                    if (!parent.exists()) {
                        parent.mkdirs();
                    }
                    try (FileOutputStream fos = new FileOutputStream(file)) {
                        int len;
                        while ((len = zis.read(buffer)) > 0) {
                            fos.write(buffer, 0, len);
                        }
                    }
                }
                entry = zis.getNextEntry();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3、运行效果展示

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值