使用mp3agic读取MP3文件时遇临时文件无法删除IOException问题
无法删除Tomcat临时文件问题解决
问题说明
运行代码时触发IO异常:
Caused by: java.io.IOException: Cannot delete C:\Users\noob234\AppData\Local\Temp\tomcat.8080.5659248991534133251\work\Tomcat\localhost\ROOT\upload_1723fa92_3db6_497a_9bdc_ac298b991fc8_00000000.tmp
尝试手动删除文件或添加1秒延迟均无法解决。当前处理MP3格式MultipartFile的代码片段如下:
public void upload (MultipartFile file){ // .... String fileName = file.getOriginalFilename(); if ("mp3".equals(extension)) { try { Mp3File mp3file = new Mp3File(fileName); sampleRate = mp3file.getSampleRate(); } catch (Exception e) { throw new Mp3Exception("Couldn't get mp3 fields: " + e.getMessage()) } } // ....
项目环境:Java 8 + Gradle,依赖配置:
implementation 'com.mpatric:mp3agic:0.9.1'
问题原因
- 错误使用文件名:
MultipartFile.getOriginalFilename()仅返回上传文件的原始名称,并非Tomcat临时文件的实际路径。直接传入Mp3File构造方法会导致mp3agic内部处理逻辑异常,未正确释放临时文件的资源句柄。 - 资源未释放:
Mp3File通过文件路径构造时会持有文件句柄,若未显式关闭,会导致Tomcat无法删除临时文件。
解决方案
方案1:使用输入流创建Mp3File(推荐)
利用MultipartFile的输入流构建Mp3File,并通过try-with-resources自动关闭流,确保资源释放:
public void upload(MultipartFile file) { // .... if ("mp3".equals(extension)) { try (InputStream inputStream = file.getInputStream()) { Mp3File mp3file = new Mp3File(inputStream); sampleRate = mp3file.getSampleRate(); } catch (Exception e) { throw new Mp3Exception("Couldn't get mp3 fields: " + e.getMessage()); } } // .... }
方案2:转存为本地临时文件处理
将MultipartFile转存到自定义临时文件,处理完成后主动清理:
public void upload(MultipartFile file) { // .... if ("mp3".equals(extension)) { File tempFile = null; try { tempFile = File.createTempFile("mp3_upload_", ".tmp"); file.transferTo(tempFile); Mp3File mp3file = new Mp3File(tempFile); sampleRate = mp3file.getSampleRate(); } catch (Exception e) { throw new Mp3Exception("Couldn't get mp3 fields: " + e.getMessage()); } finally { if (tempFile != null && tempFile.exists()) { tempFile.deleteOnExit(); // JVM退出时自动删除 // 或直接删除:tempFile.delete(); } } } // .... }
内容的提问来源于stack exchange,提问作者noob234
相关产品推荐
相关产品推荐

