前言:有时候需要对很多文件进行压缩,几个还好如果有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,如果有什么不懂的地方可以私我
彩虹屁:✨“应是上帝打翻银河,星星掉落凡间,才有这水面波光粼粼,你的眼眸 浩瀚星辰”
如果本文对你有用的话,请点个赞再走吧,谢谢!!!