java使用net.lingala.zip4j导出压缩包文件
以下是基于 zip4j 1.x 版本实现「加密压缩指定文件夹 + 压缩后删除原文件夹」的完整代码,兼容旧版依赖,同时解决加密、中文乱码、文件夹删除等核心问题:
一、先确认依赖(Maven/Gradle)
zip4j 1.x 最新稳定版为 1.3.2,需在 pom.xml 中引入:
<!-- zip4j 1.x 依赖(对应 core.ZipFile) -->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
二、完整实现代码
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import java.io.File;
import java.util.Arrays;
/**
* 基于 zip4j 1.x(core.ZipFile)实现加密压缩文件夹并删除原文件夹
*/
public class ZipEncryptUtil1x {
/**
* 加密压缩指定文件夹
* @param sourceDirPath 待压缩文件夹路径(如 D:\test\source)
* @param zipFilePath 压缩包保存路径(如 D:\test\source_encrypt.zip)
* @param password 压缩包加密密码
* @throws ZipException 压缩相关异常
*/
public static void encryptCompressDir(String sourceDirPath, String zipFilePath, String password) throws ZipException {
// 1. 校验源文件夹合法性
File sourceDir = new File(sourceDirPath);
if (!sourceDir.exists() || !sourceDir.isDirectory()) {
throw new IllegalArgumentException("源文件夹不存在或非合法目录:" + sourceDirPath);
}
// 2. 初始化压缩参数(加密+压缩配置)
ZipParameters zipParams = new ZipParameters();
// 压缩算法:DEFLATE(平衡压缩率和速度),STORE 为无压缩仅打包
zipParams.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// 压缩级别:0(最快)~9(最高压缩率),5为默认平衡值
zipParams.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
// 开启加密
zipParams.setEncryptFiles(true);
// 加密方式:AES-256(推荐,比ZIP2.0更安全)
zipParams.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
// AES密钥强度:256位(需JDK支持无限制加密策略)
zipParams.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
// 设置压缩包密码
zipParams.setPassword(password.toCharArray());
// 解决中文文件名乱码(1.x 版本需手动指定字符集)
zipParams.setFileNameCharset("UTF-8");
// 3. 创建压缩包并添加整个文件夹(保留目录结构)
ZipFile zipFile = new ZipFile(zipFilePath);
// 添加文件夹到压缩包,自动递归包含所有子文件/子目录
zipFile.addFolder(sourceDir, zipParams);
System.out.println("加密压缩完成,压缩包路径:" + zipFilePath);
// 4. 压缩完成后删除原文件夹(递归删除)
boolean deleteSuccess = deleteDirectory(sourceDir);
if (deleteSuccess) {
System.out.println("原文件夹已删除:" + sourceDirPath);
} else {
System.err.println("原文件夹删除失败(可能文件被占用):" + sourceDirPath);
}
}
/**
* 递归删除文件夹(包含所有子文件/子目录)
* @param dir 待删除的文件夹
* @return 是否删除成功
*/
private static boolean deleteDirectory(File dir) {
if (dir.isDirectory()) {
File[] children = dir.listFiles();
// 空文件夹直接删除
if (children == null || children.length == 0) {
return dir.delete();
}
// 递归删除所有子文件/子目录
for (File child : children) {
boolean success = child.isDirectory() ? deleteDirectory(child) : child.delete();
if (!success) {
return false;
}
}
}
// 最后删除空文件夹
return dir.delete();
}
// 测试示例
public static void main(String[] args) {
try {
// 待压缩文件夹路径
String sourceDir = "D:\\test\\myFolder";
// 加密压缩包保存路径
String zipFile = "D:\\test\\myFolder_encrypt.zip";
// 压缩包密码(建议包含大小写+数字+特殊字符)
String password = "Zip4j@123456";
// 执行加密压缩+删除原文件夹
encryptCompressDir(sourceDir, zipFile, password);
} catch (Exception e) {
e.printStackTrace();
System.err.println("操作失败:" + e.getMessage());
}
}
}
三、zip4j 1.x 核心配置说明(区别于2.x)
| 配置项 | 1.x 常量值 | 说明 |
|---|---|---|
| 压缩算法 | COMP_DEFLATE/COMP_STORE | DEFLATE(有压缩)、STORE(无压缩) |
| 压缩级别 | DEFLATE_LEVEL_0~DEFLATE_LEVEL_9 | 0最快,9压缩率最高,NORMAL=5(默认) |
| 加密方式 | ENC_METHOD_AES/ENC_METHOD_STANDARD | AES(安全)、ZIP2.0(弱加密,不推荐) |
| AES密钥强度 | AES_STRENGTH_128/256 | 256位需JDK解锁无限制加密策略(JDK8及以下需替换JCE文件) |
四、关键问题解决
1. AES-256 加密权限问题(JDK8及以下)
若运行时报 ZipException: Invalid AES Key Strength,需替换 JDK 加密策略文件:
- 下载「JCE 无限制强度管辖权策略文件」:Oracle 官网
- 替换路径:
JDK_HOME/jre/lib/security下的local_policy.jar和US_export_policy.jar - JDK9+ 已默认支持,无需替换。
2. 中文文件名乱码
1.x 版本需手动设置字符集:zipParams.setFileNameCharset("UTF-8"),否则压缩包内中文文件名会变成乱码。
3. 文件夹删除失败
- 原因:文件夹内文件被其他程序占用、权限不足;
- 解决:
// 删除前增加权限设置+重试逻辑 private static boolean deleteDirectory(File dir) { if (dir.isDirectory()) { File[] children = dir.listFiles(); if (children != null) { for (File child : children) { // 赋予文件可写权限 child.setWritable(true); boolean success = deleteDirectory(child); if (!success) { // 重试删除(休眠500ms) try { Thread.sleep(500); success = child.delete(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } if (!success) return false; } } } } dir.setWritable(true); return dir.delete(); }
4. 压缩包覆盖问题
若目标压缩包已存在,1.x 版本会默认追加文件,如需覆盖,需先删除已有压缩包:
File existingZip = new File(zipFilePath);
if (existingZip.exists()) {
if (!existingZip.delete()) {
throw new ZipException("已有压缩包无法删除,无法覆盖:" + zipFilePath);
}
}
// 再创建新压缩包
ZipFile zipFile = new ZipFile(zipFilePath);
五、使用注意
- 压缩包密码建议设置复杂密码(大小写+数字+特殊字符),避免被暴力破解;
- 生产环境中建议增加「压缩成功校验」(检查压缩包大小、完整性),再删除原文件夹;
- 若需压缩指定类型文件(如仅压缩
.txt),可通过FileFilter过滤:// 仅添加txt文件 zipFile.addFolder(sourceDir, zipParams, file -> file.getName().endsWith(".txt"));
该代码基于 zip4j 1.x 版本(core.ZipFile)实现,兼容旧项目依赖,可直接集成使用,核心逻辑清晰,同时处理了加密、乱码、删除失败等常见问题。
1924

被折叠的 条评论
为什么被折叠?



