Spring Boot中Tomcat临时文件删除失败(DiskFileItem.delete)报错求助
Spring Boot 3.3.0 集成Tomcat时上传文件后出现临时文件删除失败错误
错误日志
2024-06-11 11:12:40,529 ERROR [http-nio-9312-exec-5] <org.apache.juli.logging.DirectJDKLog>: Error processing request java.io.UncheckedIOException: Cannot delete C:\Windows\Temp\tomcat.9312.3138704811626004803\work\Tomcat\localhost\ROOT\upload_f2043be0_7945_4211_b735_367546c4255b_00000000.tmp at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:429) [...] 2024-06-11 11:12:40,536 ERROR [http-nio-9312-exec-5] <org.apache.juli.logging.DirectJDKLog>: Error reading request, ignored java.io.UncheckedIOException: Cannot delete C:\Windows\Temp\tomcat.9312.3138704811626004803\work\Tomcat\localhost\ROOT\upload_f2043be0_7945_4211_b735_367546c4255b_00000000.tmp at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:429) [...] 2024-06-11 11:12:40,537 ERROR [http-nio-9312-exec-5] <org.apache.juli.logging.DirectJDKLog>: Error running socket processor java.io.UncheckedIOException: Cannot delete C:\Windows\Temp\tomcat.9312.3138704811626004803\work\Tomcat\localhost\ROOT\upload_f2043be0_7945_4211_b735_367546c4255b_00000000.tmp at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.delete(DiskFileItem.java:429) [...]
问题细节
- 实际检查发现日志中提到的临时文件已不存在,但父目录
C:\Windows\Temp\tomcat.9312.3138704811626004803\work\Tomcat\localhost\ROOT\正常存在 - 已尝试配置
spring.servlet.multipart.location到自定义目录,但问题依旧,且该目录下生成的文件/文件夹即使用管理员权限也无法删除 - 错误在调用文件上传验证接口时触发,接口请求本身能正常执行,异常在请求完成后抛出
触发错误的接口代码
@PostMapping( value = "/validate", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE ) public ValidationResponse validateUploadedFile( @RequestParam("file") MultipartFile file ) { try { validator.validateMultipartFile(file); return ValidationResponse.buildValidResponse(); } catch (ValidationFailedException e) { return ValidationResponse.buildValidationFailedResponse(e); } catch (Exception e) { return ValidationResponse.buildInvalidResponse( "Unexpected exception occurred while trying to validate file: <" + e.getClass() + "> " + e.getMessage() ); } }
解决建议
1. 检查文件流是否完全关闭
在validator.validateMultipartFile(file)方法中,确保读取MultipartFile的输入流后已调用close(),或使用try-with-resources语法自动关闭流。若流未关闭,Tomcat尝试删除临时文件时会因文件被占用失败,甚至出现文件已删除但句柄未释放的情况。
2. 调整Tomcat临时文件管理策略
通过配置禁用自动删除,改用应用自行处理:
- 在
application.properties中添加:
或自定义server.tomcat.resource.cache-tomcat-workdir=false spring.servlet.multipart.resolve-lazily=trueMultipartConfigElement,设置更大的fileCleanupThreshold,或手动实现临时文件删除逻辑。
3. 排查Windows文件锁定问题
Windows系统下,临时文件可能被杀毒软件、索引服务或其他后台进程锁定:
- 使用Process Explorer工具检查是否有其他进程持有文件句柄
- 排除Tomcat临时目录的杀毒软件扫描,避免文件被锁定
4. 更换临时目录并配置权限
不要使用C:\Windows\Temp这类系统目录,改用Tomcat安装目录下的temp文件夹或自定义专属目录,并给Tomcat运行账户(如本地系统账户)赋予该目录的完全控制权限。
5. 升级Tomcat版本
Spring Boot 3.3.0默认集成的Tomcat可能存在临时文件删除bug,可在依赖管理中指定更高版本的Tomcat:
- Maven示例:
<properties> <tomcat.version>10.1.24</tomcat.version> </properties>
内容的提问来源于stack exchange,提问作者Kira Resari
相关产品推荐
相关产品推荐

