背景
springboot 项目中使用MultipartFile上传文件导入时,文件内容过大会导致页面等待时间较长,所以考虑使用上传文件时用@Async异步处理数据的方式来解决页面等待问题。
问题描述
给处理MultipartFile文件的方法添加@Async注解后,上传文件时出现异常,报错:系统找不到文件位置。
java.io.IOException: java.io.FileNotFoundException(系统找不到指定的路径。)
原因分析
前端传递过来的文件,会存储到临时文件夹中,即上面报错的文件路径位置;但是如果方法是异步执行的时候,主线程结束,临时文件就会被清空,所以会报上面的异常:
解决方案
需要通过异步处理,就需要转将文件换成输入流来操作,通过传参的方式将输入流传到异步方法内。在异步方法内使用完毕再释放输入流
@PostMapping("/asyncImportData")
public Boolean importData(@RequestParam("file") MultipartFile file) {
try {
xxxService.importData(file.getInputStream());
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// 异步处理导入的文件内容
@Async // 默认的线程池
@Async("xxxxx") // 自定义线程池
public Boolean importData(InputStream fileInputStream) throws IOException {
try {
// 文件内容处理逻辑
....
} catch (Exception e) {
log.error("导入异常", e);
}finally{
if (fileInputStream!=null){
fileInputStream.close();
}
}
}
提醒:输入流对象在异步方法使用完后记得关闭流,否则会一直占用内存资源,并且服务器本地的缓存文件也无法更改或删除