Java批量高效压缩支持加解密支持所有压缩格式(Zip/7z/rar)

前言:有时候需要对很多文件进行压缩,几个还好如果有100个呢对吧,为什么不借助咱们强大的java呢,所以我就写了一个可以批量压缩,支持所有压缩格式的工具类当然也支持加密和解密,下面就是工具类的代码
废话不多说直接上代码

Maven坐标

	    <!--Zip4j 压缩解压工具-->
        <!-- https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j -->
        <dependency>
            <groupId>net.lingala.zip4j</groupId>
            <artifactId>zip4j</artifactId>
            <version>2.9.1</version>
        </dependency>
        <!-- Commons—lang3工具 -->
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <!-- tools工具 -->
        <!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.8.4</version>
        </dependency>
        <!-- slf4j日志工具 -->
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
            <scope>compile</scope>
        </dependency>

工具类代码

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import org.apache.commons.lang3.StringUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

/**
 * @梦汐云纤 高效批量加解密压缩 支持所有压缩格式加密压缩 支持所有压缩格式加密解压 请先普通						压缩一次后再使用加密压缩 然后在使用解密
 * 支持所有压缩格式(7z / zip / zipx / rar / exe / tar / tgz / lzh / iso / gz / xz)
 */
public class BatchCompression {
    //压缩储存文件夹名称
    private static final String COMPRESSED_FOLDER = "@梦汐云纤";
    //打印日志
    private static final Logger logger = LoggerFactory.getLogger(BatchDecompression.class);

    public static void main(String args[]) throws ZipException {
        //将文件路径下的所有文件夹进行压缩处理
        compressAllFiles("E:\\测试\\", ".7z");
        compressAllFiles("E:\\测试\\", ".zip");
        compressAllFiles("E:\\测试\\", ".rar");
        //将压缩好的压缩文件进行加密压缩处理 请先普通压缩一次后再使用加密压缩
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".7z", "666");
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".zip", "666");
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".rar", "666");
        //解压加密双层压缩 只有第一层设有密码 此方法会自动执行两次解压请勿修改字符集否则中文乱码 文件储存在源文件下的@梦汐云纤文件夹里面
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\7z\\", ".7z", "666", "UTF8");
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\zip\\", ".zip", "666", "UTF8");
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\rar\\", ".rar", "666", "UTF8");
    }

    /**
     * 遍历路径下指定压缩格式获取所有文件并批量解压加密文件
     *
     * @param path     文件路径
     * @param suffix   后缀
     * @param password 密码
     */
    public static void pressurizedEncryption(String path, String suffix, String password, String charset) {
        //路径储存集合
        ArrayList<String> listFileName = new ArrayList<String>();
        //获取文件名称
        File file = new File(path);
        String[] names = file.list();
        if (names != null) {
            String[] completeNames = new String[names.length];
            for (int i = 0; i < names.length; i++) {
                completeNames[i] = path + names[i];
            }
            //将路径添加到listFileName 集合内
            listFileName.addAll(Arrays.asList(completeNames));
            //遍历路径并解压加密文件
            for (String name : listFileName) {
                // 指定的压缩格式			          排除名为@梦汐云纤的文件夹
                if (name.contains(suffix) && !name.equals(COMPRESSED_FOLDER)) {
                    try {
                        //调用解压加密方法
                        uncompress(new File(name), password, suffix, charset);
                    } catch (ZipException e) {
                        logger.debug("压缩文件异常:{}", e.getMessage());
                    }
                }
            }
        }
    }

    /**
     * 遍历路径下指定压缩格式获取所有文件并批量加密压缩
     *
     * @param path     文件路径
     * @param suffix   后缀
     * @param password 密码
     */
    public static void encryptionCompressedAllFiles(String path, String suffix, String password) {
        //路径储存集合
        ArrayList<String> listFileName = new ArrayList<String>();
        //获取文件名称
        File file = new File(path);
        String[] names = file.list();
        if (names != null) {
            String[] completeNames = new String[names.length];
            for (int i = 0; i < names.length; i++) {
                completeNames[i] = path + names[i];
            }
            //将路径添加到listFileName 集合内
            listFileName.addAll(Arrays.asList(completeNames));
            //遍历路径并加密压缩
            for (String name : listFileName) {
                // 指定的压缩格式			          排除名为@梦汐云纤的文件夹
                if (name.contains(suffix) && !name.equals(COMPRESSED_FOLDER)) {
                    try {
                        compress(new File(name), password, suffix);
                    } catch (ZipException e) {
                        logger.debug("压缩文件异常:{}", e.getMessage());
                    }
                }
            }
        }
    }

    /**
     * 遍历路径下指定压缩格式获取所有文件并批量压缩
     *
     * @param path   文件目录
     * @param suffix 后缀
     */
    public static void compressAllFiles(String path, String suffix) {
        //储存路径的集合
        ArrayList<String> listFileName = new ArrayList<String>();
        //获取文件名称
        File file = new File(path);
        String[] names = file.list();
        if (names != null) {
            String[] completeNames = new String[names.length];
            for (int i = 0; i < names.length; i++) {
                completeNames[i] = path + names[i];
            }
            //将路径添加到listFileName 集合内
            listFileName.addAll(Arrays.asList(completeNames));
            //创建线程
            Thread[] thread = new Thread[5];
            //遍历路径并压缩
            for (String name : listFileName) {
                //截取要压缩的文件夹名称
                String fileName = name.substring(name.lastIndexOf("\\") + 1);
                //      排除名为@梦汐云纤的文件夹
                if (!fileName.equals(COMPRESSED_FOLDER)) {
                    //调用多线程进行压缩
                    CompressionThreadPool compressionThreadPool = new CompressionThreadPool(path, fileName, suffix);
                    for (int i = 0; i < 5; i++) {
                        thread[i] = new Thread(compressionThreadPool);
                        thread[i].start();
                    }
                }
            }
        }
    }

    /**
     * 压缩方法
     *
     * @param filePath 文件目录
     * @param fileName 文件名称
     * @param suffix   后缀
     * @throws Exception 异常
     */
    public static void zipCompression(String filePath, String fileName, String suffix) throws Exception {
        //开始时间
        long startTime = System.currentTimeMillis();
        String path = filePath + COMPRESSED_FOLDER + "\\" + fileName;
        //不存在则在源文件下创建名为@梦汐云纤的文件夹
        File file = new File(path);
        if (!file.exists() && !file.isDirectory()) {
            new File(filePath + COMPRESSED_FOLDER).mkdir();
        }
        //创建.zip文件
        OutputStream is = new FileOutputStream(path + suffix);
        //检查输出流,采用CRC32算法,保证文件的一致性
        CheckedOutputStream cos = new CheckedOutputStream(is, new CRC32());
        //创建zip文件的输出流
        ZipOutputStream zos = new ZipOutputStream(cos);
        //设置编码,防止中文乱码
        zos.setEncoding("GBK");
        //需要压缩的文件或文件夹对象
        file = new File(filePath + fileName);
        //压缩文件的具体实现函数
        ZipFile(zos, file, fileName, path);
        //关闭流
        zos.close();
        cos.close();
        is.close();
        //结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("压缩成功: " + fileName + "耗时:" + (endTime - startTime) + "ms");
    }

    /**
     * 递归,获取需要压缩的文件夹下面的所有子文件,然后创建对应目录与文件,对文件进行压缩
     *
     * @param zos      文件输出流
     * @param file     需要压缩的文件或文件夹对象
     * @param fileName 文件名称
     * @param path     储存压缩路径
     * @throws Exception
     */
    public static void ZipFile(ZipOutputStream zos, File file, String fileName, String path) throws Exception {
        if (file.isDirectory()) {
            //创建压缩文件的目录结构
            zos.putNextEntry(new ZipEntry(file.getPath().substring(file.getPath().indexOf(fileName)) + File.separator));
            for (File f : file.listFiles()) {
                ZipFile(zos, f, fileName, path);
            }
        } else {
            //打印输出正在压缩的文件
            System.err.println("正在压缩文件: " + fileName + "————>" + file.getName());
            //创建压缩文件
            zos.putNextEntry(new ZipEntry(file.getPath().substring(file.getPath().indexOf(fileName))));
            //用字节方式读取源文件
            InputStream is = new FileInputStream(file.getPath());
            //创建一个缓存区
            BufferedInputStream bis = new BufferedInputStream(is);
            //字节数组,每次读取1024个字节
            byte[] b = new byte[1024];
            //循环读取,边读边写
            while (bis.read(b) != -1) {
                //写入压缩文件
                zos.write(b);
            }
            //关闭流
            bis.close();
            is.close();
        }
    }

    /**
     * 加密压缩方法
     *
     * @param sourceFile 压缩源文件路径
     * @param password   密码
     */
    public static void compress(File sourceFile, String password, String suffix) throws ZipException {
        File dir = new File(sourceFile.getParent() + "\\" + COMPRESSED_FOLDER + "\\" + File.separator + suffix.substring(suffix.lastIndexOf(".") + 1));
        if (!dir.exists() && !dir.isDirectory()) {
            new File(sourceFile.getParent() + File.separator + COMPRESSED_FOLDER + "\\" + suffix.substring(suffix.lastIndexOf(".") + 1)).mkdirs();
        }
        // 文件名
        String fileName = sourceFile.getName();
        // 文件名称(不含扩展名)
        String realName = fileName.substring(0, fileName.lastIndexOf("."));
        String targetPathname = dir.getAbsolutePath() + File.separator + realName + suffix;
        File targetFile = new File(targetPathname);
        ZipParameters zipParameters = new ZipParameters();
        ZipFile zipFile = new ZipFile(targetFile);
        // 是否加密
        if (StringUtils.isNotBlank(password)) {
            zipParameters.setEncryptFiles(true);
            zipParameters.setEncryptionMethod(EncryptionMethod.AES);
            zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
            zipFile.setPassword(password.toCharArray());
        }
        try {
            zipFile.addFile(sourceFile, zipParameters);
            logger.info("压缩成功:{}", fileName);
        } catch (Exception e) {
            logger.debug("压缩文件异常:{}", e.getMessage());
        }
    }

    /**
     * 解压加密方法
     *
     * @param sourceFile 解压源文件路径
     * @param password   密码
     */
    public static void uncompress(File sourceFile, String password, String suffix, String charset) throws ZipException {
        //文件路径
        String targetPath = sourceFile.getParent() + File.separator + COMPRESSED_FOLDER;
        File dir = new File(targetPath);
        if (!dir.exists() && !dir.isDirectory()) {
            dir.mkdir();
        }
        ZipFile zipFile = new ZipFile(sourceFile);
        //设置字符集防止中文乱码
        zipFile.setCharset(Charset.forName(charset));
        try {
            if (zipFile.isEncrypted()) {
                zipFile.setPassword(password.toCharArray());
            }
            zipFile.extractAll(targetPath);
            //解压内层压缩文件 无密码留空 设置GBK防止中文乱码
            pressurizedEncryption(targetPath + "\\", suffix, "", "GBK");
            logger.info("解压成功:{}", sourceFile.getName());
        } catch (ZipException e) {
            logger.debug("压缩文件异常:{}", e.getMessage());
        }
    }

    //线程池 压缩线程
    public static class CompressionThreadPool implements Runnable {
        private static String path = "";//文件路径
        private static String fileName = "";//文件名称
        private static String suffix = "";//后缀

        //接收参数方法
        public CompressionThreadPool(String path, String fileName, String suffix) {
            CompressionThreadPool.path = path;
            CompressionThreadPool.fileName = fileName;
            CompressionThreadPool.suffix = suffix;
        }

        public void run() {
            try {
                //调用压缩方法
                zipCompression(path, fileName, suffix);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

食用方法

 public static void main(String args[]) {
        //将文件路径下的所有文件夹进行压缩处理
        compressAllFiles("E:\\测试\\", ".7z");
        compressAllFiles("E:\\测试\\", ".zip");
        compressAllFiles("E:\\测试\\", ".rar");
        //将压缩好的文件进行加密压缩处理 请先普通压缩一次后再使用加密压缩
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".7z", "666");
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".zip", "666");
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".rar", "666");
        //解压加密双层压缩 只有第一层设有密码 此方法会自动执行两次解压请勿修改字符集否则中文乱码 文件储存在源文件下的@梦汐云纤文件夹里面
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\7z\\", ".7z", "666", "UTF8");
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\zip\\", ".zip", "666", "UTF8");
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\rar\\", ".rar", "666", "UTF8");
    }

测试数据

在这里插入图片描述
此处有两个文件夹
在这里插入图片描述
在这里插入图片描述
文件夹内可以包含任意文件

无密码压缩测试

    public static void main(String args[]) {
        //将文件路径下的所有文件或文件夹进行压缩处理
        compressAllFiles("E:\\测试\\", ".7z");
        compressAllFiles("E:\\测试\\", ".zip");
        compressAllFiles("E:\\测试\\", ".rar");
    }

此处多了一个文件夹
在这里插入图片描述
压缩文件全在里面
在这里插入图片描述
都可正常查看在这里插入图片描述

加密压缩测试

    public static void main(String args[]) {
        //将压缩好的zip进行加密压缩处理
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".7z", "666");
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".zip", "666");
        encryptionCompressedAllFiles("E:\\测试\\@梦汐云纤\\", ".rar", "666");
    }

在这里插入图片描述
格式分类在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
都可正常查看和解压
在这里插入图片描述

解压加密测试

    public static void main(String args[]) throws ZipException {
        //解压加密双层压缩 只有第一层设有密码 此方法会自动执行两次解压请勿修改字符集否则中文乱码 文件储存在源文件下的@梦汐云纤文件夹里面
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\7z\\", ".7z", "666", "UTF8");
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\zip\\", ".zip", "666", "UTF8");
        pressurizedEncryption("E:\\测试\\@梦汐云纤\\@梦汐云纤\\rar\\", ".rar", "666", "UTF8");
    }

压缩好的分类格式
在这里插入图片描述
在这里插入图片描述
这个绿色框里面的就是解压出来的源文件,因为是双层压缩目录结果基本一样不要搞混了哦
在这里插入图片描述
在这里插入图片描述
一切正常OK,如果有什么不懂的地方可以私我在这里插入图片描述
彩虹屁:✨“应是上帝打翻银河,星星掉落凡间,才有这水面波光粼粼,你的眼眸 浩瀚星辰”
如果本文对你有用的话,请点个赞再走吧,谢谢!!!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值