此工具类可以压缩和解压文件,支持设置解压密码。
说明:
1 压缩文件时候判定被压缩文件是否存在, 不存在会报错。
2 示例是压缩txt,也可以doc,pdf,xlsx等其他文件。
3 压缩和解压不同文件类型可通用,但解压不同文件类型读取内容的写法略有不同。
4 依赖包zip4j_1.3.1.jar, ant.jar
zipUtil.java
package zipTest;
import java.io.BufferedInputStream;
/**
* 文件压缩加密码解密工具类
*
* @author yulisao
* @createDate 2020年8月21日
*/
public class zipUtil {
private static final int BUFFER_SIZE = 2 * 1024;
/**
* 加密单个压缩文件
*
* @param zipFile 完整路径输出压缩包
* @param addFile 被压缩文件
* @param password 解压密码
*/
public static void encryZipFile(File zipFile,File addFile,String password){
if (!addFile.exists()) {
return;
}
try {
//创建压缩文件
ZipFile respFile = new ZipFile(zipFile);
//设置压缩文件参数
ZipParameters parameters = new ZipParameters();
//设置压缩方法
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
//设置压缩级别
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//设置压缩文件加密
parameters.setEncryptFiles(true);
//设置加密方法
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
//设置aes加密强度
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//设置密码
parameters.setPassword(password);
//添加文件到压缩文件
respFile.addFile(addFile,parameters);
} catch (ZipException e) {
e.printStackTrace();
}
System.out.println("压缩成功,文件存储路径 " + zipFile.getAbsolutePath());
}
/**
* 加密单多压缩文件
*
* @param zipFile 完整路径输出压缩包
* @param addFile 被压缩文件
* @param password 解压密码
*/
public static void encryZipFiles(File zipFile,ArrayList<File> filesList,String password){
try {
//创建压缩文件
ZipFile respFile = new ZipFile(zipFile);
//设置压缩文件参数
ZipParameters parameters = new ZipParameters();
//设置压缩方法
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
//设置压缩级别
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//设置压缩文件加密
parameters.setEncryptFiles(true);
//设置加密方法
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
//设置aes加密强度
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//设置密码
parameters.setPassword(password);
//添加文件到压缩文件
respFile.addFiles(filesList,parameters);
} catch (ZipException e) {
e.printStackTrace();
}
System.out.println("压缩成功,文件存储路径 " + zipFile.getAbsolutePath());
}
/**
* 压缩指定的多个文件(不设置密码 )
*
* @param fileList 文件列表
* @param outPath 压缩包输出路径
*/
public static void zipFile(List<File> fileList , String outPath) {
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(new FileOutputStream(new File(outPath)));
for (File file : fileList) {
byte[] buf = new byte[BUFFER_SIZE];
zos.putNextEntry(new ZipEntry(file.getName()));
int len;
FileInputStream in = new FileInputStream(file);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
} catch (Exception e) {
throw new RuntimeException("zip file run error!",e);
} finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("压缩成功,文件存储路径 " + outPath);
}
/**
* 压缩文件/文件夹(不设置密码 )
*
* @param targetFilePath 源文件路径
* @param outZipPath 压缩后文件存储路径
* @param isDeleteOld 压缩后是否删除源文件
*/
public static void compressToZip(String targetFilePath, String outZipPath, boolean isDeleteOld) {
File targetFile = new File(targetFilePath); // 被压缩路径
File zipFile = new File(outZipPath); // 压缩包输出路径
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) { //java7 支持自动关闭流
writeToZip(targetFile, "", zos);
if (isDeleteOld) {
deleteDir(targetFile); //压缩完后删原件
}
System.out.println("压缩成功,文件存储路径 " + outZipPath);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e.getCause());
}
}
/**
* 回归处理
*
* @param targetFile 源文件目录
* @param currentDir 压缩文件目录
* @param zos 文件流
*/
private static void writeToZip(File targetFile, String currentDir, ZipOutputStream zos) {
if (targetFile.isDirectory()) { // 若当前处理的是目录, 循环回归
currentDir += targetFile.getName() + File.separator;
File[] files = targetFile.listFiles();
for (File file : files) {
writeToZip(file, currentDir, zos);
}
} else { // 若当前处理的是文件, 压缩
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile))) {
ZipEntry zipEntry = new ZipEntry(currentDir + targetFile.getName());
zos.putNextEntry(zipEntry);
int len;
byte[] buffer = new byte[1024 * 10];
while ((len = bis.read(buffer, 0, buffer.length)) != -1) {
zos.write(buffer, 0, len);
zos.flush();
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e.getCause());
}
}
}
/**
* 删除文件夹
*
* @param targetDir
* @return
*/
private static boolean deleteDir(File targetDir) {
// 是文件就循环回归,是文件就直接delete,
if (targetDir.isDirectory()) {
String[] children = targetDir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(targetDir, children[i]));
if (!success) {
return false;
}
}
}
return targetDir.delete(); // 删除文件
}
/**
* 压缩文件/文件夹(不设置密码 ,减少中文乱码)
*
* @param targetFilePath 被压缩目标路径
* @param zipFilePath 压缩包输出路径
*/
public static void compressToZip(String targetFilePath, String zipFilePath) {
File zipFile = new File(zipFilePath);
File targetFile = new File(targetFilePath);
if (!targetFile.exists()){
throw new RuntimeException(targetFilePath + "不存在!");
}
Project prj = new Project();
Zip zip = new Zip();
zip.setProject(prj);
zip.setDestFile(zipFile);
FileSet fileSet = new FileSet(); // FileSet的方法很多,比如setExcludes:过滤不压缩,具体可以参阅文档
fileSet.setProject(prj);
fileSet.setDir(targetFile);
zip.addFileset(fileSet);
zip.execute();
System.out.println("压缩成功,文件存储路径 " + zipFilePath);
}
/**
* 解密
*
* @param zipFilePath 压缩文件
* @param outPath 解压路径
* @param password 解压密码
* @throws ZipException
* @throws IOException
*/
public static void decryptZipFile(String zipFilePath, String outPath, String password) throws ZipException, IOException {
ZipFile zipFile = new ZipFile(zipFilePath);
zipFile.setFileNameCharset("GBK");//设置编码格式
if (!zipFile.isValidZipFile()) {
throw new ZipException("文件不合法或不存在");
}
if (zipFile.isEncrypted()) { //检查是否需要密码
zipFile.setPassword(password);
}
if (StringUtils.isBlank(outPath)) { // 默认解压到当前路径
outPath = zipFilePath.substring(0,zipFilePath.lastIndexOf(File.separator));
} else { // 检查目录是否存在
File outDir = new File(outPath);
if (!outDir.exists()) {
outDir.mkdir();
}
}
outPath = outPath.endsWith(File.separator) ? outPath:outPath+File.separator;
List<FileHeader> fileHeaderList = zipFile.getFileHeaders(); // 获取解压文件
for (int i = 0; i < fileHeaderList.size(); i++) {
FileHeader fileHeader = fileHeaderList.get(i);
// 文件输出
InputStream input = zipFile.getInputStream(fileHeader);// 获取流
int index;
byte[] bytes = new byte[1024];
FileOutputStream downloadFile = new FileOutputStream(outPath + fileHeader.getFileName());// 创建同原文件名文件写入
while ((index = input.read(bytes)) != -1) {
downloadFile.write(bytes, 0, index);
downloadFile.flush();
}
downloadFile.close();
input.close();
// 读取文件内容
BufferedReader reader = new BufferedReader(new InputStreamReader(zipFile.getInputStream(fileHeader)));
String line;
try {
while ((line = reader.readLine()) != null) {
System.out.println(line); // and do something
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("解压成功至 " + outPath);
}
}
测试类
package zipTest;
import java.io.File;
/**
* 压缩包工具类测试主类
*
* @author yulisao
* @createDate 2020年8月26日
*/
public class zipUtilTest {
public static void main(String[] args) {
String pwd = "123456";
String filePath1 = "C:\\Users\\Administrator\\Desktop\\ziptest\\11.txt"; // 被压缩的文件
String filePath2 = "C:\\Users\\Administrator\\Desktop\\ziptest\\22.txt"; // 被压缩的文件
String filePath3 = "C:\\Users\\Administrator\\Desktop\\ziptest"; // 被压缩的文件
String zipPath1 = "C:\\Users\\Administrator\\Desktop\\outtest\\single.zip" ; // 压缩包输出
String zipPath2 = "C:\\Users\\Administrator\\Desktop\\outtest\\double.zip" ; // 压缩包输出
String zipPath3 = "C:\\Users\\Administrator\\Desktop\\outtest\\nopwd.zip" ; // 压缩包输出
String zipPath4 = "C:\\Users\\Administrator\\Desktop\\outtest\\all.zip" ; // 压缩包输出
String zipPath5 = "C:\\Users\\Administrator\\Desktop\\outtest\\allant.zip" ; // 压缩包输出
File file = new File(filePath1);
File zipFile1 = new File(zipPath1);
File zipFile2 = new File(zipPath2);
// 单个文件压缩
zipUtil.encryZipFile(zipFile1,file,pwd);
// 多个文件压缩
ArrayList<File> filesList = new ArrayList<File>();
File file1 = new File(filePath1);
if (!file1.exists()) {
return;
}
filesList.add(file1);
File file2 = new File(filePath2);
if (!file2.exists()) {
return;
}
filesList.add(file2);
// 有多少文件继续加....
zipUtil.encryZipFiles(zipFile2,filesList,pwd);
// 无密压缩
zipUtil.zipFile(filesList, zipPath3);
// 无密压缩文件夹,依赖 ant.jar
zipUtil.compressToZip(filePath3, zipPath5);
// 无密压缩文件夹,递归
zipUtil.compressToZip(filePath3, zipPath4, false);
System.err.println("解密开始");
// 解密
String zipPath = "C:\\Users\\Administrator\\Desktop\\outtest\\double.zip" ; // 压缩包输出
String outPath = "C:\\Users\\Administrator\\Desktop\\outtest\\decrypt\\";
try {
zipUtil.decryptZipFile(zipPath,outPath, pwd);
} catch (IOException e) {
e.printStackTrace();
} catch (ZipException e) {
e.printStackTrace();
}
}
}
运行结果: