了解到有两种解压 zip 文件的方式:org.apache.tools.zip.ZipFile ;SpringBoot 自带的 net.lingala.zip4j.core.ZipFile 。这里选择第二种。
引入 POM 依赖:
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.1</version>
</dependency>
1. Zip 文件导入
FileController 添加一个接口:
@PostMapping("/importZipFile")
public ResultVo<String> importZipFile(@RequestParam("zipFile") MultipartFile zipFile) {
return fileService.importZipFile(zipFile);
}
FileServiceImpl :
public ResultVo<String> importZipFile(MultipartFile zipFile) {
ResultVo<String> resultVo = checkZipFileParam(zipFile);
if (!resultVo.checkSuccess()) {
return resultVo;
}
ResultVo<String> uploadFileResultVo = uploadFile(zipFile);
if (!uploadFileResultVo.checkSuccess()) {
return uploadFileResultVo;
}
String uploadZipFilePath = uploadFileResultVo.getData();
boolean unPackZip = FileUtil.unPackZip(new File(uploadZipFilePath), "", FileUtil.getUploadZipPath(), true);
if (!unPackZip) {
return ResultVoUtil.error("【导入Zip文件】失败");
}
log.info("【导入Zip文件】成功");
return ResultVoUtil.success("【导入Zip文件】成功");
}
checkZipFileParam() :校验Zip文件的入参
public ResultVo<String> checkZipFileParam(MultipartFile zipFile) {
if (Objects.isNull(zipFile)) {
return ResultVoUtil.error("【导入Zip文件】缺少Zip包");
}
String contentType = zipFile.getContentType();
if (!FileConstant.CONTENT_TYPE_ZIP.equals(contentType) && !FileConstant.CONTENT_TYPE_ZIP_COMPRESSED.equals(contentType)) {
return ResultVoUtil.error("【导入Zip文件】上传的文件类型不是Zip");
}
return ResultVoUtil.success();
}
FileConstant :文件常量类
public interface FileConstant {
String UTF8 = "UTF-8";
String GBK = "GBK";
String CONTENT_TYPE_ZIP = "application/zip";
String CONTENT_TYPE_ZIP_COMPRESSED = "application/x-zip-compressed";
}
FileUtil.unPackZip() :解压
public static boolean unPackZip(File zipFile, String password, String desPath, boolean isDel) {
try {
ZipFile zip = new ZipFile(zipFile);
zip.setFileNameCharset(FileConstant.GBK);
log.info("【文件解压】begin unpack zip file....");
zip.extractAll(desPath);
if (zip.isEncrypted()) {
zip.setPassword(password);
}
} catch (ZipException e) {
log.error("【文件解压】异常,路径:{} ,异常信息:{} ", desPath, e);
return false;
}
if (isDel) {
zipFile.deleteOnExit();
}
return true;
}
说明:
- 解压缩时,需要设置文件编码的类型。
Linux/Mac 系统默认是 UTF-8 ;windows 系统默认是 GBK deleteOnExit() :在虚拟机终止时,请求删除此抽象路径名表示的文件或目录;delete() 方法:直接删除
getUploadZipPath() :获取Zip文件上传路径
public static String getUploadZipPath() {
return fileConfig.getUploadZipPath();
}
FileConfig :添加一个属性
public class FileConfig {
private String uploadPath;
private String downloadPath;
private String uploadZipPath;
}
application.yml :
file:
uploadPath: E:/upload
downloadPath: E:/download
uploadZipPath: E:/uploadZipPath
2. Zip 导出
FileController :添加一个Zip文件下载接口
@PostMapping("/exportZipFile")
public ResultVo exportZipFile(final HttpServletResponse response) {
return fileService.exportZipFile(response);
}
FileServiceImpl :导出Zip文件
public ResultVo<String> exportZipFile(HttpServletResponse response) {
String srcPath = getSrcPathByCondition();
String desPath = FileUtil.packZip(srcPath, FileUtil.getDownloadZipPath(), false, null);
if (StringUtil.isBlank(desPath)) {
log.error("【文件压缩】压缩失败");
return ResultVoUtil.error("【文件压缩】压缩失败");
}
log.info("【文件压缩】压缩成功,压缩文件路径为:{}", desPath);
ResultVo<String> downLoadZipResultVo = downloadFile(desPath, response);
if (null != downLoadZipResultVo && !downLoadZipResultVo.checkSuccess()) {
log.error("【导出Zip文件】下载文件失败");
return downLoadZipResultVo;
}
boolean deleteFile = FileUtil.deleteFile(new File(desPath));
if (!deleteFile) {
log.error("【下载Zip文件】删除临时文件失败,临时文件路径为{}", desPath);
return ResultVoUtil.error("删除临时文件失败");
}
log.info("【下载Zip文件】删除临时文件成功,临时文件路径为:{}", desPath);
return null;
}
getSrcPathByCondition() :获取要压缩的源路径
public String getSrcPathByCondition() {
return "E:/upload/2021-11-11";
}
FileUtil.packZip() :压缩Zip文件。对于给定的文件(夹)压缩到指定位置
public static String packZip(String srcPath, String desPath, boolean isCreateDir, String password) {
File srcFile = new File(srcPath);
desPath = buildDestinationZipFilePath(srcFile, desPath);
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if (!StringUtil.isBlank(password)) {
parameters.setEncryptFiles(true);
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
parameters.setPassword(password.toCharArray());
}
try {
ZipFile zipFile = new ZipFile(desPath);
log.info("【文件压缩】begin pack zip file....");
if (srcFile.isDirectory()) {
if (!isCreateDir) {
File[] subFiles = srcFile.listFiles();
ArrayList<File> files = new ArrayList<>();
Collections.addAll(files, subFiles);
zipFile.addFiles(files, parameters);
} else {
zipFile.addFolder(srcFile, parameters);
}
} else {
zipFile.addFile(srcFile, parameters);
}
return desPath;
} catch (ZipException e) {
log.error("【压缩ZiP文件】失败,失败信息为:{}", e);
return null;
}
}
buildDestinationZipFilePath() :构建压缩文件存放路径
public static String buildDestinationZipFilePath(File srcFile,String destParam) {
if (!StringUtil.isBlank(destParam) && destParam.endsWith(FileConstant.ZIP_FILE_SUFFIX)) {
return destParam;
}
if (srcFile.isDirectory()) {
destParam = srcFile.getParent() + File.separator + srcFile.getName() + FileConstant.ZIP_FILE_SUFFIX;
} else {
String fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf("."));
destParam = srcFile.getParent() + File.separator + fileName + FileConstant.ZIP_FILE_SUFFIX;
}
return destParam;
}
FileConstant
public interface FileConstant {
...
String FILE_SPLIT = "/";
}
FileConfig :
public class FileConfig {
...
private String downloadZipPath;
}
application.yml
file:
uploadPath: E:/upload
downloadPath: E:/download
uploadZipPath: E:/uploadZipPath
downloadZipPath: E:/downloadZipPath
|