首先我要说,阿里云的批量下载 确实有点坑 不是说不好使,而是根本就找不到,上网搜也没什么靠谱的,后来一狠心,把多个文件放在zip下载,接下来看实现
/***
* 批量下载(zip)
* @param objectName
* @param response
* @throws IOException
* fileName为前端传过来的多个文件路径字符串,用逗号隔开
* @author panfei
* @date 2019年7月24日
*/
@RequestMapping("downAllOssFile")
@ResponseBody
public void downAllOssFile(@RequestParam("fileName") String objectName,HttpServletRequest request, HttpServletResponse response) throws IOException {
try {
String momentFileName = "全部资源下载.zip";
// 创建临时文件
File zipFile = File.createTempFile("批量下载", ".zip");
FileOutputStream f = new FileOutputStream(zipFile);
CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
// 用于将数据压缩成Zip文件格式
ZipOutputStream zos = new ZipOutputStream(csum);
String[] files = objectName.split(",");
for (String string : files) {
String fName = string.trim();
String eachFileName = fName.substring(fName.lastIndexOf("/")+1);
String tmp = fName.substring(0,fName.lastIndexOf("/"));
tmp = tmp.substring(tmp.lastIndexOf("/")+1);
String fileName = tmp + "/" + eachFileName;
OSSObject ossObject = OSSFactory.build().downloadOssFile(response.getOutputStream(), fileName);
InputStream inputStream = ossObject.getObjectContent();
zos.putNextEntry(new ZipEntry(eachFileName));
int bytesRead;
// 向压缩文件中输出数据
while((bytesRead = inputStream.read())!=-1){
zos.write(bytesRead);
}
inputStream.close();
zos.closeEntry();
}
zos.close();
String header = request.getHeader("User-Agent").toUpperCase();
if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
momentFileName = URLEncoder.encode(momentFileName, "utf-8");
momentFileName = momentFileName.replace("+", "%20"); //IE下载文件名空格变+号问题
} else {
momentFileName = new String(momentFileName.getBytes(), "ISO8859-1");
}
response.reset();
response.setContentType("text/plain");
response.setContentType("application/octet-stream; charset=utf-8");
response.setHeader("Location", momentFileName);
response.setHeader("Cache-Control", "max-age=0");
response.setHeader("Content-Disposition", "attachment; filename=" + momentFileName);
FileInputStream fis = new FileInputStream(zipFile);
BufferedInputStream buff = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
byte[] car = new byte[1024];
int l=0;
while (l < zipFile.length()) {
int j = buff.read(car, 0, 1024);
l += j;
out.write(car, 0, j);
}
// 关闭流
fis.close();
buff.close();
out.close();
// 删除临时文件
zipFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
package com.sanshan.modules.oss;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.springframework.web.multipart.MultipartFile;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.sanshan.common.util.RRException;
/**
* 阿里云存储
*
* @author panfei
*
* @date 2019-07-23 16:22
*/
public class AliyunCloudStorageService extends CloudStorageService {
private OSSClient client;
public AliyunCloudStorageService(CloudStorageConfig config) {
this.config = config;
//初始化
init();
}
private void init() {
client = new OSSClient(config.getAliyunEndPoint(), config.getAliyunAccessKeyId(),
config.getAliyunAccessKeySecret());
}
@Override
public OSSObject downloadOssFile(OutputStream os, String objectName) throws IOException {
// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
OSSObject ossObject = client.getObject(config.getAliyunBucketName(), objectName);
return ossObject;
}
}
点击下载全部资源
打开后
完事儿
主要的流程就是把前端传过来的路径参数字符串解析后遍历,然后去阿里云oss中获取文件按流的方式输出进临时创建的zip压缩文件中,最后把临时的压缩文件也用流输出,输出到页面上,临时生成的文件记得删掉,删不掉说明流没有关闭