前端请求:
{
"env_23211211_out": ["1080431045908779009","1080434473292681218"],
"env_23211212_out": ["1080431045908779009","1080434473292681218"]
}
文件结构:
temp
UUID文件夹(zip文件)
env_23211211_out(指定文件夹)
1080431045908779009(文件夹下的文件1的ID,根据这个ID查数据库获取该文件在服务器中的路径)
1080434473292681218(文件夹下的文件2的ID)
******PathUtils中的Copy方法可以用IOUtils.copy()方法代替*********
Controller
/**
* 根据文件夹批量下载文件
*/
@PostMapping("/downloadFilesByDiffDir")
public void downloadFilesByDiffDir(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "fileName", required = false) String fileName,
@RequestBody Map<String,Object> map){
fileName = StringUtils.isBlank(fileName) ? "files" : fileName;
fileInfoService.downloadFilesByDiffDir(request, response, fileName, map);
}
Service
/**
* 根据文件夹批量下载文件
*
* @param request http请求
* @param response http响应
* @param fileName 打包文件名称
* @param map Key是文件夹名,Value是文件id数组
*/
@Override
@SuppressWarnings("unchecked")
public void downloadFilesByDiffDir(HttpServletRequest request, HttpServletResponse response,
String fileName, Map<String, Object> map) {
//1.拼接temp文件夹路径
String tempPath = baseFilePath + TEMP;
File file = new File(tempPath);
if (!file.exists()) {
file.mkdirs();
}
//2.每次请求过来在temp文件夹下根据当前的时间创建一个文件夹
String zipName = new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date());
String currRequestPath = tempPath + "/" + zipName;
File currRequestFile = new File(currRequestPath);
if (!currRequestFile.exists()) {
currRequestFile.mkdirs();
}
//3.依次取出map的key,在当前时间文件夹下面创建与key名字一致的文件夹
Set<String> keys = map.keySet();
for (String key : keys) {
//拼接文件夹路径
String eachDirPath = currRequestPath + "/" + key;
File eachDirFile = new File(eachDirPath);
if (!eachDirFile.exists()) {
eachDirFile.mkdirs();
}
//读取对应的value值
List<String> value = (List<String>) map.get(key);
//遍历该数组,取出对应的值,将其对应的文件拷贝到当前文件夹下
for (String id : value) {
FileInfo fileInfo = getById(id);
//原来是"\\"
String originFilePath = baseFilePath + fileInfo.getFolder() + "/" + fileInfo.getSaveName();
File originFile = new File(originFilePath);
if (!originFile.exists()) {
continue;
}
String eachFilePath = eachDirPath + "/" + fileInfo.getName();
//将原始文件拷贝到map中指定的文件夹
PathUtils.copyFile(originFilePath, eachFilePath);
}
}
//4.将时间下面的所有子文件夹和文件打包成zip下载
String zipPath = currRequestPath + ".zip";
try {
PathUtils.pack(currRequestPath, zipPath);
} catch (IOException e) {
e.printStackTrace();
}
//5.将生成的zip文件发送给浏览器
//响应头的设置
response.reset();
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
String downloadName = fileName + ".zip";
response.setHeader("Content-Disposition", "attachment;filename=\"" + downloadName + "\"");
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(new File(zipPath)));
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
byte[] b = new byte[1000];
int length = 0;
while ((length = inputStream.read(b)) != -1) {
outputStream.write(b, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
//6.删除服务器生成的临时文件夹和zip文件
PathUtils.deleteFile(new File(zipPath));
PathUtils.deleteFile(new File(currRequestPath));
}
PathUtils
package com.envision.utils;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 文件相关的工具类
*
* @author kbse
*/
public class PathUtils {
private static Logger logger = LoggerFactory.getLogger(PathUtils.class);
/**
* 删除文件(夹)及其子文件(夹)
*
* @param file 文件
*/
public static void deleteFile(File file) {
if (!file.exists()) {
return;
}
if (file.isFile()) {
file.delete();
} else if (file.isDirectory()) {
try {
FileUtils.deleteDirectory(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 拷贝文件
*
* @param oldPath 文件源路径
* @param newPath 文件目标路径
*/
public static void copyFile(String oldPath, String newPath) {
try {
int byteread = 0;
File oldfile = new File(oldPath);
File newfile = new File(newPath);
//文件存在时
if (oldfile.exists()) {
//读入源文件
InputStream inStream = new FileInputStream(oldfile);
OutputStream fs = new FileOutputStream(newfile);
byte[] buffer = new byte[1000];
while ((byteread = inStream.read(buffer)) != -1) {
fs.write(buffer, 0, byteread);
}
inStream.close();
fs.close();
}
} catch (Exception e) {
logger.error("复制单个文件操作出错");
e.printStackTrace();
}
}
/**
* 将 sourceDirPath 压缩成 zipFilePath 压缩包
*
* @param sourceDirPath 源文件目录 eg: D:/data
* @param zipFilePath 压缩包文件目录 eg: D:/data.zip
* @throws IOException 文件相关异常
*/
public static void pack(String sourceDirPath, String zipFilePath) throws IOException {
Path p = Files.createFile(Paths.get(zipFilePath));
try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) {
Path pp = Paths.get(sourceDirPath);
Files.walk(pp)
.filter(path -> !Files.isDirectory(path))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
try {
zs.putNextEntry(zipEntry);
Files.copy(path, zs);
zs.closeEntry();
} catch (IOException e) {
logger.error("pack file error src: {} msg: ", sourceDirPath, e.getMessage());
}
});
}
}
}
本文介绍了一个用于批量下载文件的API实现,包括前端请求格式、后端处理流程及文件操作方法。详细展示了如何根据文件夹和文件ID从服务器批量下载文件,并通过Zip压缩包返回给客户端。
2100

被折叠的 条评论
为什么被折叠?



