<!--文件压缩和解压工具类-->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.7.1</version>
</dependency>
package com.example.demo.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

import java.io.*;

/**
* 压缩文件和解压缩文件(公用工具类)
*
* @author gblfy
* @date 2020-10-12
*/
@Slf4j
public class ZipReduceUtil {
private static final int CACHE_SIZE = 1024;//文件读取缓冲区大小
private static final String CHINESE_CHARSET = "GBK"; //使用GBK编码可以避免压缩中文文件名乱码

//windows环境待压缩的文件路径
public static final String wPath = "D:\\cmiip_Dir\\000000\\";
//linux环境待压缩的文件路径
public static final String linuxPath = "/app/cmiip_Dir/00000/";

/**
* 单元测试压缩
*/
public static void main(String[] args) {

//应用待上传zip的前缀路径
String localPath = "D:\\cmiip_Dir\\";
//上传文件种类(类型)前缀
String uploadPrefix = "S";
//存量和增量标志
String flag = "I";
//批次号
String batchNo = "0000000001";


//待压缩的指定文件目录(文件夹)
String wSourceFolder = wPath;
// String lSourceFolder = linuxPath;

//压缩文件统一处理
ZipReduceDeal(localPath, uploadPrefix, batchNo, flag, wSourceFolder);
}
/**
* 单元测试解压缩
*/
// public static void main(String[] args) throws Exception {
// ZipReduceUtil jzb = new ZipReduceUtil();
//
// String sourceZip = "D:\\cmiip_Dir\\S_I_0000000001_020.zip";
// String destDir = "D:\\cmiip_Dir\\";
// jzb.unZip(destDir, sourceZip);
// }

/**
* 压缩文件夹为.zip到指定目录
*
* @param localPath 应用待上传zip的前缀路径
* @param uploadPrefix 上传文件种类(类型)前缀
* @param batchNo 批次号
* @param flag 存量和增量的标识
* @param sourceFolder 压缩后的.zip绝对路径
*/
public static void ZipReduceDeal(String localPath, String uploadPrefix, String batchNo, String flag, String sourceFolder) {

//将待压缩的指定文件目录(文件夹) 转换成文件类型的目录
File fileNum = converFileTypeDir(sourceFolder);

//获取压缩后指定文件夹下的
long getlist = getlist(fileNum);

//压缩完成后的zip的输出路径
String zipOutputFilePath = localPath + uploadPrefix + "_" + flag + "_" + batchNo + "_0" + getlist + ".zip";
//压缩完成后的zip的输出路径 转换成文件类型的目录
File zipFilePath = converFileTypeDir(zipOutputFilePath);

//开始压缩指定文件夹
zip(sourceFolder, zipFilePath);
}

/**
* 压缩文件
*
* @param sourceFolder 压缩文件夹
* @param zipFilePath 压缩文件输出路径
*/
public static void zip(String sourceFolder, File zipFilePath) {
log.debug("待压缩的目录路径: {} 压缩后的zip包路径为: {}", sourceFolder, zipFilePath);

OutputStream os = null;
BufferedOutputStream bos = null;
ZipOutputStream zos = null;
try {
os = new FileOutputStream(zipFilePath);
bos = new BufferedOutputStream(os);
zos = new ZipOutputStream(bos);
// 解决中文文件名乱码
zos.setEncoding(CHINESE_CHARSET);
File file = new File(sourceFolder);
String basePath = null;
if (file.isDirectory()) {
//压缩文件夹
basePath = file.getPath();
} else {
basePath = file.getParent();
}
//压缩文件
zipFile(file, basePath, zos);

} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (zos != null) {
zos.closeEntry();
zos.close();
}
if (bos != null) {
bos.close();
}
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}


/**
* 压缩文件
*
* @param parentFile 待压缩文件夹
* @param basePath
* @param zos
* @throws Exception
*/
private static void zipFile(File parentFile, String basePath, ZipOutputStream zos) throws Exception {
File[] files = new File[0];
if (parentFile.isDirectory()) {
files = parentFile.listFiles();
} else {
files = new File[1];
files[0] = parentFile;
}
String pathName;
InputStream is;
BufferedInputStream bis;
byte[] cache = new byte[CACHE_SIZE];
for (File file : files) {
if (file.isDirectory()) {
pathName = file.getPath().substring(basePath.length() + 1) + File.separator;
zos.putNextEntry(new ZipEntry(pathName));
zipFile(file, basePath, zos);
} else {
pathName = file.getPath().substring(basePath.length() + 1);
is = new FileInputStream(file);
bis = new BufferedInputStream(is);
zos.putNextEntry(new ZipEntry(pathName));
int nRead = 0;
while ((nRead = bis.read(cache, 0, CACHE_SIZE)) != -1) {
zos.write(cache, 0, nRead);
}
bis.close();
is.close();
}
}
}

/**
* 获取指定文件夹下的文件数量
*
* @param f
* @return
*/
public static long getlist(File f) {//递归求取目录文件个数
log.debug("开始从 {} 路径下面获取指文件数量", f);
long size = 0;
File flist[] = f.listFiles();
size = flist.length;
for (int i = 0; i < flist.length; i++) {
if (flist[i].isDirectory()) {
size = size + getlist(flist[i]);
size--;
}
}
return size;
}

/**
* 将String类型的目录转换为文件类型的目录
*
* @param fileDir
* @return
*/
public static File converFileTypeDir(String fileDir) {
return new File(fileDir);
}


/**
* 解压缩
*
* @param destDir 解压缩后的目标目录 d:/cmiip_Dir
* @param sourceZip 源zip文件 d:/cmiip_Dir/S_I_0000000001_020.zip
* 结果则是 将d:/cmiip_Dir/S_I_0000000001_020.zip文件解压缩到d:/cmiip_Dir目录下
*/
public void unZip(String destDir, String sourceZip) {

try {
Project prj1 = new Project();
Expand expand = new Expand();
expand.setProject(prj1);
expand.setSrc(new File(sourceZip));
expand.setOverwrite(false);//是否覆盖
File f = new File(destDir);
expand.setDest(f);
expand.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}