在SpringBoot项目中,如果我们想要下载多个文件,可以考虑将文件打成zip压缩包,通过ZipOutputStream流的方式进行下载,不保存压缩后的文件。
下面是工具类 ZipFileUtils 代码:
public class ZipFileUtils {
/**
* web下载打成压缩包的文件--流方式
*
* @param response 响应
* @param fileList 文件列表
* @param zipName 压缩包名
*/
public static void downloadZipFiles(HttpServletResponse response, List<String> fileList, String zipName) {
ZipOutputStream zipOutputStream = null;
try {
//设置响应头
response.reset();
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
//设置文件名称
response.setHeader("Content-Disposition", "attachment;filename=" + zipName);
zipOutputStream = new ZipOutputStream(response.getOutputStream());
for (String file : fileList) {
toZip(zipOutputStream, new File(file));
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
//关闭资源
if (null != zipOutputStream) {
try {
zipOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 压缩文件
*
* @param zipOutputStream 压缩文件流
* @param file 待压缩文件
*/
private static void toZip(ZipOutputStream zipOutputStream, File file) {
String filename = file.getName();
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(Files.newInputStream(file.toPath()));
//设置压缩包内文件的名称
zipOutputStream.putNextEntry(new ZipEntry(filename));
int size;
byte[] buffer = new byte[4096];
while ((size = bis.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, size);
}
zipOutputStream.closeEntry();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
//关闭资源
if (null != bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Controller使用示例:
@GetMapping("/testZip")
public void testZip(HttpServletResponse response) {
ArrayList<String> fileList = new ArrayList<>();
//文件路径
fileList.add("././license/key/private.key");
fileList.add("././license/key/public.key");
ZipFileUtils.downloadZipFiles(response,fileList,"test.zip");
}