minio使用踩坑
问题:
使用minio下载文件,文件下载正常,但是再控制台中会显示一个错误:
UT010015: Could not delete file C:\xx\xx\xx
开发环境
- spring boot 3.1.0
- undertow
相关代码
public void download(String filaName, HttpServletResponse response) {
try (InputStream inputStream = minioTemplate.downloadFile(filaName)) {
OssFile ossFile = minioTemplate.statFile(filaName);
// 设置响应头
// 设置字节流,并设置使用编码为UTF-8
filaName="测试文件.bat";
String encode = URLEncoder.encode(filaName, StandardCharsets.UTF_8);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + StringPool.QUOTE + encode + StringPool.QUOTE);
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(ossFile.getLength()));
// 将输入流写入响应输出流中
ServletOutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
outputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
造成错误原因
这里注意下关闭流的两句代码
outputStream.flush();
outputStream.close();
因为这里手动刷新流,并且关闭了,导致后续undertow服务器删除临时文件的时候找不到文件,所有造成报错
后来查了资料:由于 ServletOutputStream 是通过 response.getOutputStream() 获取的,它是由 Servlet 容器负责管理和关闭的,因此不需要手动关闭。在 try-with-resources 块结束时,只会自动关闭 InputStream,而 ServletOutputStream 会由 Servlet 容器负责关闭。
所以,对于给定的代码示例,关闭 outputStream 的操作是多余的,可以将其移除。代码会在块结束时自动关闭 InputStream,而 ServletOutputStream 会由 Servlet 容器在适当的时候关闭。
所有不需要手动关闭
解决方案
直接把这两句代码删除即可
修改之后的代码
public void download(String filaName, HttpServletResponse response) {
try (InputStream inputStream = minioTemplate.downloadFile(filaName)) {
OssFile ossFile = minioTemplate.statFile(filaName);
// 设置响应头
// 设置字节流,并设置使用编码为UTF-8
filaName="测试文件.bat";
String encode = URLEncoder.encode(filaName, StandardCharsets.UTF_8);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + StringPool.QUOTE + encode + StringPool.QUOTE);
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(ossFile.getLength()));
// 将输入流写入响应输出流中
ServletOutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}