Spring boot 文件下载 文件压缩
2018-10-22 本文已影响0人
金刚_30bf
文件下载
代码:
@GetMapping("/download")
public ResponseEntity<FileSystemResource> downloadFile(HttpServletRequest request) {
// 获取上送参数
String currentPath = request.getParameter("currentPath");
String subPath = request.getParameter("subPath");
String fileName = request.getParameter("fileName");
String download = request.getParameter("download");
String dpath = "";
String dname = "";
boolean isfail = false;
String msg = "";
log.debug("下载文件请求参数: " + currentPath + " " + subPath + " " + fileName + " " + download);
// 下载目录时, 检查 download 为1 , 压缩目录 root + currentPath + subPath
if (StringUtils.equals(download, "1")) {
String tmppath = FileUtil.contactPath(currentPath, subPath);
String dirpath = FileUtil.contactPath(this.fileRoot, tmppath);
String zipname = ".zip";
if (StringUtils.isBlank(tmppath) || StringUtils.equals(tmppath, File.separator)) {
// 当tmppath 为空时, 取名为 root
zipname = "root" + zipname;
} else {
String[] strs = tmppath.split(Matcher.quoteReplacement(File.separator));
zipname = strs[strs.length - 1] + zipname;
}
// zip 文件保存路径
// 使用随机字符串生成路径
String zippath = FileUtil.contactPath(this.download_root, UUID.randomUUID().toString());
log.debug("开始压缩文件: " + dirpath + " " + zippath + " " + zipname);
try {
FileUtil.folder2zip(dirpath, zippath, zipname);
} catch (Exception exp) {
log.error("压缩文件出现异常 :" ,exp);
isfail = true;
msg = "压缩文件异常:" + exp.getMessage();
}
dpath = FileUtil.contactPath(zippath, zipname);
dname = zipname;
} else {
// 下载文件时, 检查 fileName不空 , 路径为 root + currentPath + fileName
if (StringUtils.isBlank(fileName)) {
log.debug("下载文件时, 上送文件名称为空!");
isfail = true;
msg ="下载文件时, 上送文件名称为空!";
} else {
dpath = FileUtil.contactPath(this.fileRoot, FileUtil.contactPath(currentPath, fileName));
dname = fileName;
}
}
log.info("下载文件路径及名称:" + dpath + " " + dname);
if (isfail) {
log.info("下载失败" + msg);
return null;
}
return this.export(new File(dpath));
/**
else {
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName=" + dname);// 设置文件名
File file = new File(dpath);
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
os.close();
return ;
} catch (Exception e) {
log.error("读取下载文件异常!" , e);
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
log.error("" , e);
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
log.error("" , e);
e.printStackTrace();
}
}
}
}
**/
}
public ResponseEntity<FileSystemResource> export(File file) {
if (file == null) {
return null;
}
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
return ResponseEntity
.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new FileSystemResource(file));
}
下载使用的是 ResponseEntity<FileSystemResource> , 若使用方法中注释的部分, 直接写response, 可能会报异常 : 写流已打开.
UT010006: Cannot call getWriter(), getOutputStream() already called
文件夹压缩
代码:
/**
* 压缩当前目录path下的所有文件 , 生成文件名称为 zipname , 放在路径zippath下 ;
* 有异常则抛出 ;
* @param path
* @param zippath
* @param zipname
* @throws IOException
*/
public static void folder2zip(String path, String zippath, String zipname) {
File src = new File(path);
ZipOutputStream zos = null;
if (src == null || !src.exists() || !src.isDirectory()) {
// 源目录不存在 或不是目录 , 则异常
logger.error("压缩源目录不存在或非目录!" + path);
throw new RuntimeException("压缩源目录不存在或非目录!" + path);
}
File destdir = new File(zippath);
if (!destdir.exists()) {
// 创建目录
logger.info("压缩目标路径不存在, 创建之." + zippath);
destdir.mkdirs();
}
File zipfile = new File(contactPath(zippath, zipname));
File[] srclist = src.listFiles();
if (srclist == null || srclist.length == 0) {
// 源目录内容为空,无需压缩
logger.error("源目录内容为空,无需压缩下载!" + path);
throw new RuntimeException("源目录内容为空,无需压缩下载!" + path);
}
try {
zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipfile)));
// 递归压缩目录下所有的文件 ;
compress(zos, src, src.getName());
zos.close();
} catch (FileNotFoundException e) {
logger.error("压缩文件不存在", e);
throw new RuntimeException("压缩目标文件不存在!" + e.getMessage());
} catch (IOException e) {
logger.error("压缩文件IO异常", e);
throw new RuntimeException("压缩文件IO异常!" + e.getMessage());
}
finally {
if (zos != null) {
try {
zos.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}
/**
* 递归压缩文件
* @param zos
* @param src
* @throws IOException
*/
private static void compress(ZipOutputStream zos, File src, String name) throws IOException {
if (src == null || !src.exists()) {
return ;
}
if (src.isFile()) {
byte[] bufs = new byte[10240];
ZipEntry zentry = new ZipEntry(name);
zos.putNextEntry(zentry);
logger.debug("压缩:" + src.getAbsolutePath());
FileInputStream in = new FileInputStream(src);
BufferedInputStream bin = new BufferedInputStream(in, 10240);
int readcount = 0 ;
while( (readcount = bin.read(bufs, 0 , 10240)) != -1) {
zos.write(bufs, 0 , readcount);
}
zos.closeEntry();
bin.close();
} else {
// 文件夹
File[] fs = src.listFiles();
if (fs == null || fs.length == 0 ) {
zos.putNextEntry(new ZipEntry(name + File.separator ));
zos.closeEntry();
return ;
}
for (File f : fs) {
compress(zos, f, name + File.separator + f.getName());
}
}
}
注意: 如何保留原压缩目录的结构 .