依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.20</version>
</dependency>
代码
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @description: 文件或者文件夹压缩工具类
* @create: 2021-08-05 14:17
**/
public class ZipFilesUtils {
private static final Logger logger = LoggerFactory.getLogger(ZipFilesUtils.class);
/**
* 默认文件名
*/
private static final String DEFAULT_ZIP_FILENAME = "source";
private static final String ITEM_TYPE_STRING = "string";
private static final String ITEM_TYPE_FILE = "file";
/**
* 压缩文件
*
* @param files 文件List,仅支持List<String>和List<File>
* @param zipFileName 压缩后的文件名
* @param response 响应流
* @date 2021/8/5 15:02
*/
public static void compressFiles(List<?> files,
String zipFileName,
HttpServletResponse response) {
if (CollectionUtils.isEmpty(files)) {
try {
logger.error("The file list can not be empty !!!");
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
if (files.get(0) instanceof String) {
compressFilesToZip(ITEM_TYPE_STRING, files,
zipFileName, response);
} else if (files.get(0) instanceof File) {
compressFilesToZip(ITEM_TYPE_FILE, files,
zipFileName, response);
} else {
logger.error("The files type is not support!");
}
}
@SuppressWarnings("unchecked")
private static void compressFilesToZip(String itemTypeString,
List<?> files,
String zipFileName,
HttpServletResponse response) {
String fileName = StringUtils.isBlank(zipFileName) ? DEFAULT_ZIP_FILENAME + ".zip" : zipFileName + ".zip";
response.setContentType("application/octet-stream;charset=utf-8");
try {
response.setHeader("Content-Disposition",
"attachment;fileName=" +
fileName + ";filename*=utf-8''" +
URLEncoder.encode(fileName, "utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try (OutputStream outputStream = response.getOutputStream()) {
if (ITEM_TYPE_STRING.equals(itemTypeString)) {
List<File> fileList = new ArrayList<>();
for (Object file : files) {
fileList.add(new File((String) file));
}
compress(fileList, new ZipArchiveOutputStream(outputStream));
} else {
compress((List<File>) files, new ZipArchiveOutputStream(outputStream));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void compress(List<File> fileList,
ZipArchiveOutputStream zipArchiveOutputStream) {
try {
doCompress(fileList, zipArchiveOutputStream, null);
zipArchiveOutputStream.finish();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 执行压缩的方法
*
* @param fileList 文件或者文件夹的list,可以既包含文件和文件夹
* @param zipArchiveOutputStream 输出流
* @param parent 父路径,递归用的,初始为null
* @date 2021/8/5 18:41
*/
private static void doCompress(List<File> fileList,
ZipArchiveOutputStream zipArchiveOutputStream,
String parent) throws IOException {
for (File file : fileList) {
if (!file.exists()) {
return;
}
if (file.isFile()) {
try (InputStream inputStream = new FileInputStream(file)) {
zipArchiveOutputStream.setUseZip64(Zip64Mode.AsNeeded);
if (null != parent) {
zipArchiveOutputStream.putArchiveEntry(new ZipArchiveEntry(parent + File.separator + file.getName()));
} else {
zipArchiveOutputStream.putArchiveEntry(new ZipArchiveEntry(file.getName()));
}
byte[] buffer = new byte[10240];
int len;
while ((len = inputStream.read(buffer)) != -1) {
zipArchiveOutputStream.write(buffer, 0, len);
}
zipArchiveOutputStream.closeArchiveEntry();
} catch (Exception e) {
e.printStackTrace();
}
} else {
File[] files = file.listFiles();
if (files == null || files.length == 0) {
if (null != parent) {
zipArchiveOutputStream.putArchiveEntry(new ZipArchiveEntry(parent + File.separator + file.getName() + "/"));
} else {
zipArchiveOutputStream.putArchiveEntry(new ZipArchiveEntry(file.getName() + "/"));
}
zipArchiveOutputStream.closeArchiveEntry();
} else {
if (null != parent) {
doCompress(Arrays.asList(files), zipArchiveOutputStream, parent + File.separator + file.getName());
} else {
doCompress(Arrays.asList(files), zipArchiveOutputStream, file.getName());
}
}
}
}
}
}
使用方法
List<File> list = new ArrayList<>();
//文件夹
list.add(new File("E:\\home"));
//文件
list.add(new File("E:\\study\\other\\test.7z"));
ZipFilesUtils.compressFiles(list,"文件名" ,response);
response
参数为HttpServletResponse