环境
jdk 1.8、springboot 2.4.5、maven 3.6.2、slf4j
解压文件maven依赖:
<!-- Apache Commons Compress,用于压缩/解压 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
Controller接口
@RequestMapping(value = "/uploadZipFile", method = RequestMethod.POST)
public void uploadCompressedFile(@RequestParam("file") MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
String uploadZipPath = "G:\\outFile";
// 根据文件扩展名判断并处理
assert fileName != null;
if (fileName.endsWith(".zip")) {
// 处理 .zip 文件
FileUtils.unzip(file, uploadZipPath);
} else if (fileName.endsWith(".tar.gz") || fileName.endsWith(".tgz")) {
// 处理 .tar.gz 文件
FileUtils.unTarGz(file, uploadZipPath);
} else {
throw new IllegalArgumentException("不支持的文件类型,请上传.zip/.tar.gz格式文件");
}
log.info("上传的压缩文件 {} ----------> 到指定路径 {} 并解压 -----------> 已完成", fileName, uploadZipPath);
}
FileUtils工具类方法
/**
* 解压zip文件
* @param file
* @throws IOException
*/
public static void unzip(MultipartFile file, String uploadZipPath) throws IOException {
String fileName = file.getOriginalFilename();
String filePath = uploadZipPath + File.separator + fileName;
File zipFile = new File(filePath);
file.transferTo(zipFile);
String outputBaseName = fileName.substring(0, fileName.lastIndexOf("."));
// 检查解压目标是否存在,如果存在则删除以准备覆盖
File potentialOutputDir = new File(uploadZipPath, outputBaseName);
if (potentialOutputDir.exists()) {
// 递归删除目录及其内容,注意这将永久删除原有文件,请谨慎使用
deleteDirectory(potentialOutputDir);
log.info("已删除存在的文件/目录准备覆盖解压: {}", potentialOutputDir.getAbsolutePath());
}
ZipFile zip = new ZipFile(zipFile);
Enumeration<ZipArchiveEntry> entries = zip.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
File destPath = new File(uploadZipPath, entry.getName());
if (entry.isDirectory()) {
destPath.mkdirs();
} else {
destPath.getParentFile().mkdirs();
try (InputStream in = zip.getInputStream(entry);
FileOutputStream out = new FileOutputStream(destPath)) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
}
}
zip.close();
zipFile.delete();
}
/**
* 解压tar.gz文件
* @param tarGzFile
* @throws IOException
*/
public static void unTarGz(MultipartFile tarGzFile, String uploadZipPath) throws IOException {
String fileName = tarGzFile.getOriginalFilename();
File outputFileDir = new File(uploadZipPath);
String outputBaseName = fileName.replace(".tar.gz", "");
// 检查解压目标是否存在,如果存在则删除以准备覆盖
File potentialOutputDir = new File(uploadZipPath, outputBaseName);
if (potentialOutputDir.exists()) {
// 递归删除目录及其内容,注意这将永久删除原有文件,请谨慎使用
deleteDirectory(potentialOutputDir);
log.info("已删除存在的文件/目录准备覆盖解压: {}", potentialOutputDir.getAbsolutePath());
}
// 处理 .tar.gz 文件
try (InputStream fileStream = tarGzFile.getInputStream();
BufferedInputStream bufferedIn = new BufferedInputStream(fileStream);
TarArchiveInputStream tarIn = new TarArchiveInputStream(new GzipCompressorInputStream(bufferedIn))) {
TarArchiveEntry entry;
while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {
String entryName = entry.getName();
File outputFile = new File(outputFileDir, entryName);
if (entry.isDirectory()) {
// 如果是目录,则创建它
if (!outputFile.exists()) {
outputFile.mkdirs();
}
} else {
// 确保目标文件的父目录存在
outputFile.getParentFile().mkdirs();
try (FileOutputStream out = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[1024];
int len;
while ((len = tarIn.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
}
}
}
}
}