背景
之前项目中的文本下载都是后台传给前台内容,然后由前台去完成内容的展示与下载,但是目前针对大文本文件还是采用这种方式的话,用户体验很差,前台会变得非常慢。
解决
针对这种问题,我们考虑是否可以通过流的形式将数据刷新前台进行下载,经过检测,速度确实比之前要快了很多。针对这些大文本,我们选择的是数据库只存文件的全路径信息,文件内容等需要下载或查询时才回去获取。废话不多,以下是简单的demo代码实现,可以根据待下载文件预估大小,调整buffer数组的大小。
@GetMapping("demo/download/{id}")
public void downloadDemo(@PathVariable String id, HttpServletRequest request , HttpServletResponse response) {
//根据主键id去查找需要下载文件的文件地址
ResultDemo resultDemo = iResultDemoService.getById(id);
byte[] buffer = new byte[1024];
InputStream inputStream = null;
BufferedInputStream bis = null;
OutputStream os = null; //输出流
try {
//根据文件地址,获取一个文件输入流
inputStream = new FileInputStream(resultDemo.getFilePath());
//设置返回文件信息
response.setContentType("application/octet-stream;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(resultDemo.getFileName(), "UTF-8"));
//将内容使用字节流写入输出流中
os = response.getOutputStream();
bis = new BufferedInputStream(inputStream);
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (FileNotFoundException e) {
log.error("下载资源未找到异常,e",e);
} catch (IOException e) {
log.error("IO流异常,e",e);
} finally {
//关闭流信息
try {
if (inputStream != null) {
inputStream.close();
}
if (bis != null) {
bis.close();
}
if (os != null) {
os.flush();
os.close();
}
} catch (IOException e) {
log.error("关闭流出现异常,e:",e);
}
}
}