报错
在文件上传接口,解析文件的时候报错,报错信息如下:
s.w.m.s.StandardServletMultipartResolver :
Failed to perform cleanup of multipart items
java.io.UncheckedIOException: Cannot delete C:\Users\username\AppData\Local\Temp\tomcat.8080.xxxx\work\Tomcat\localhost\ROOT\upload_xxxx_00000000.tmp
使用场景描述
从文件上传接口,上传表格文件,然后对表格的内容进行解析,将解析出的数据存入数据库。
需要从接口参数 MultipartFile
中,获取到 InputStream
,以供之后 解析数据逻辑 使用。
文件上传接口,业务逻辑能够正常执行。但是,控制台会报出如上的错误。
报错原因
使用完 InputStream
之后,没有关闭。导致 tomcat 临时文件无法删除。
解决办法就是,使用完InputStream
后,关闭它。
解决方案
1. @Cleanup(推荐)
使用 Lombok 的 @Cleanup
注解,释放资源。
@Cleanup
InputStream inputStream;
代码示例:
@PostMapping("upload")
@ApiOperation(value = "上传表格文件,解析表格", notes = "")
public String upload(MultipartFile file) {
// 表格文件校验逻辑。
// 解析表格,需要从 MultipartFart 获取到输入流 InputStream。
try {
// 输入流需要关闭,使用 @Cleanup 注解,否则会报异常。
@Cleanup
InputStream inputStream = file.getInputStream();
// 表格解析业务逻辑。
} catch (IOException e) {
e.printStackTrace();
System.out.println("IOException:" + e);
}
return "文件上传成功";
}
2. IOUtils.closeQuietly
使用 IOUtils.closeQuietly
方法,释放资源。此方法需要在 finally 代码块中使用。
IOUtils.closeQuietly(inputStream);
示例代码:
import org.apache.tomcat.util.http.fileupload.IOUtils;
@PostMapping("upload")
@ApiOperation(value = "上传表格文件,解析表格", notes = "")
public String upload(MultipartFile file) {
// 表格文件校验逻辑。
// 解析表格,需要从 MultipartFart 获取到输入流 InputStream。
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
// 表格解析业务逻辑。
} catch (IOException e) {
e.printStackTrace();
System.out.println("IOException:" + e);
} finally {
IOUtils.closeQuietly(inputStream);
}
return "文件上传成功";
}
3. InputStream.close()
此方法为 Java InputStream 提供的默认方法。
直接关闭输出流。close() 方法,需要在 finally 中调用。
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
代码示例:
@PostMapping("upload")
@ApiOperation(value = "上传表格文件,解析表格", notes = "")
public String upload(MultipartFile file) {
// 表格文件校验逻辑。
// 解析表格,需要从 MultipartFart 获取到输入流 InputStream。
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
// 表格解析业务逻辑。
} catch (IOException e) {
e.printStackTrace();
System.out.println("IOException:" + e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "文件上传成功";
}