Spring Boot 3.1.2升级后旧版Windows Server无法删除临时文件
问题描述
升级Spring Boot至3.1.2版本并切换到JDK17后,在低于Windows Server 2022的服务器上运行应用时,文件上传出现临时文件无法删除的错误,报错信息如下:
ERROR 07.04.24 06:49:59,284 [https-jsse-nio-8585-exec-3] Http11Processor Error processing request java.io.UncheckedIOException: Cannot delete C:\Users\test\AppData\Local\Temp\tomcat.8585.7214288071310798307\work\Tomcat\localhost\ROOT\upload_80353576_cb85_40bc_938c_3088b7428c44_00142374.tmp at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:429) ~[test.jar:?] ... Caused by: java.io.IOException: Cannot delete C:\Users\test\AppData\Local\Temp\tomcat.8585.7214288071310798307\work\Tomcat\localhost\ROOT\upload_80353576_cb85_40bc_938c_3088b7428c44_00142374.tmp ... 13 more
Windows 10及Windows Server 2022环境下无此问题。
解决方案
显式关闭文件输入流
处理MultipartFile时,确保文件输入流被正确关闭,避免旧Windows系统锁定文件。推荐使用try-with-resources语法自动管理流:try (InputStream inputStream = multipartFile.getInputStream()) { // 处理文件逻辑 } catch (IOException e) { // 异常处理 }若未使用try-with-resources,需在处理完成后手动调用
inputStream.close()。配置自定义临时文件目录
避开系统默认的Temp目录,指定应用专属的临时目录,降低权限冲突概率。在application.properties中添加以下配置:# 自定义Spring Boot Multipart临时目录 spring.servlet.multipart.location=./app-multipart-temp # 自定义Tomcat基础目录(包含临时文件) server.tomcat.basedir=./tomcat-base-temp # 确保请求结束后清理临时文件(默认已开启,显式声明更稳妥) spring.servlet.multipart.cleanup-after-request=true需保证应用对该目录有读写权限。
添加JVM启动参数
JDK17在旧Windows系统上的文件处理逻辑可能存在兼容性问题,添加以下参数禁用Alternate Data Streams(ADS):-Djdk.io.File.enableADS=false调整Tomcat版本
Spring Boot 3.1.2默认绑定Tomcat 10.1.x,部分版本在旧Windows上存在临时文件删除bug。可尝试升级Tomcat至10.1.15+(该版本修复了部分Windows文件锁定问题),或在pom.xml中指定兼容版本:<properties> <tomcat.version>10.1.15</tomcat.version> </properties>手动触发临时文件删除
若以上方案无效,可在请求处理完成后,手动获取临时文件路径并删除:// 获取MultipartFile对应的临时文件 File tempFile = ((DiskFileItem) ((StandardMultipartHttpServletRequest) request).getFile("file").getStorageDescriptor()).getStoreLocation(); // 在请求结束后异步删除 new Thread(() -> { try { Thread.sleep(1000); // 延迟删除,确保文件已释放 Files.delete(tempFile.toPath()); } catch (Exception e) { e.printStackTrace(); } }).start();注意:需处理删除失败的异常,避免日志污染。
内容的提问来源于stack exchange,提问作者Gowri
相关产品推荐
相关产品推荐

