我的web应用程序是在Spring MVC上制作的。我有一个功能,用户可以更改他/她的个人资料图片。我正在将该文件作为mutlipart文件发送到服务器。每次用户上传图片时,文件的名称都保持不变。
用户第一次上传新图片时,它会被更改,但如果用户第二次上传新照片,它会抛出异常。
我的代码
File newImage = new File(profileFolder + File.separator + fileNewName + fileExt);
if(newImage.exists())
{
newImage.delete();
}
imageFile.transferTo(newImage);
我收到一个异常
java.io.IOException: Destination file [FILE_NAME] already exists and could not be deleted
at org.springframework.web.multipart.commons.CommonsMultipartFile.transferTo(CommonsMultipartFile.java:137)
at controllers.MainController.uploadFile(MainController.java:2087)
请帮我解决这个问题。
问题是应用程序无法删除图像文件的现有副本来创建新文件。
newImage.delete()
调用可能返回false
,表示它没有删除该文件。
既然你在Windows上,有两种可能的解释:
-
可能存在权限问题,无法删除旧图像文件。(错误消息表明文件存在,这意味着目录路径是正确的,目录是可读的。但运行JVM的"用户"可能无法更新它。)
-
旧图像文件可能已打开。Windows通常会在文件打开时锁定文件,这样可以防止文件被删除。
我认为,这可能是第二个选项,因为图像显示在有更改图片方法的页面上。我怎样才能强行关闭它?
你需要在你的应用程序中找到打开图像文件的代码,并确保总是在完成读取后立即关闭它。推荐的方法是使用"try with resource"。例如
try (InputStream is = new FileInputStream(somePath)) {
// Do stuff with 'is'
}
当try
块终止时,is
资源将自动关闭。
如果您找不到/修复资源泄漏,或者文件正被另一个应用程序打开,那么问题(AFAIK)是棘手的。
我不认为这是权限问题或文件锁定问题,因为如果问题与文件有关,也应该复制到第一种情况。
为什么要删除图像,然后作为transferTo()进行传输,自动删除目标处的文件。
我认为这可能奏效。
现在,我认为答案与文件锁定有关。当您调用transferTo()方法时,它必须打开一个流,该流将文件传输到文件系统,并且该流保持打开状态。开放的流正在制造问题。
如果你想删除任何文件,你必须关闭它的所有引用,但在你的情况下,它仍然是打开的。