Files.move和Files.copy抛出java.nio.file.FileAlreadyExistsException异常

14

我想删除一个文件并将另一个文件重命名为旧文件,但是我无法移动此文件,因为Java会抛出java.nio.file.FileAlreadyExistsException异常。以下是我正在使用的代码片段

static void swapData(String origFilePath, String tempFilePath) throws IOException{

        Path tempPath = FileSystems.getDefault().getPath(tempFilePath);
        Path origPath = FileSystems.getDefault().getPath(origFilePath);
        try{
            String origFileName = null;
            File origFileRef = new File(origFilePath);
            if(Files.exists(origPath)){
                origFileName = origFileRef.getName();
                Files.delete(origPath);
                if(Files.exists(origPath))
                    throw new IOException("cannot able to delete original file");
            }
            if(origFileName != null)
                Files.move(tempPath, tempPath.resolveSibling(origFileName), StandardCopyOption.REPLACE_EXISTING);
        }catch(IOException e){
            throw e;
        }
    }

我收到的异常信息如下:在此处输入图片描述
出现在Files.move(tempPath, tempPath.resolveSibling(origFileName), StandardCopyOption.REPLACE_EXISTING);

同时,当我在Windows资源管理器中查看此文件时,它的缩略图存在,但无法打开。我不明白为什么会这样,如果我正在使用REPLACE_EXISTING,为什么还会抛出FileAlreadyExistsException异常。

我还编辑了之前的问题,因为它没有清楚说明。

请帮忙解决。
Anuj


1
你能告诉我你的“to”和“from”目录吗? - Abdul Fatir
2
你确定这不是一个简单的本地文件系统权限问题吗?顺便说一句:我认为你把路径搞混了?'destPath' 存储到了 'moveFrom'。也许只是个人喜好,但目标应该是目标位置(“moveTo”);)编辑 关于权限:您是否检查过文件是否已打开,以及您的用户是否有权限访问它并写入目标目录? - DoNuT
1
请参考新提出的问题。 - aga
1
看一下这个:https://dev59.com/UWQn5IYBdhLWcg3wAjPJ#17169700。 - Janki Gadhiya
1个回答

19

在运行Files.moveFiles.copy时,请检查是否有另一个线程正在占用相同的文件资源。我遇到了相同的异常和文件访问症状,并且能够在对文件访问进行序列化后解决问题。

此外,在执行Files.copyFiles.move时,使用REPLACE_EXISTING选项,您无需编写删除原始文件并重命名tmp的多个步骤,尽管Files.moveFiles.copy不能保证是原子操作。虽然存在ATOMIC_MOVE选项,但我不喜欢实现特定的保证,如javadoc所述,如果文件已存在,则可能会抛出IOException异常。

ATOMIC_MOVE:将移动作为原子文件系统操作执行,所有其他选项都将被忽略。如果目标文件存在,则其替换现有文件还是通过引发IOException异常来失败是由实现特定的。如果无法将移动视为原子文件系统操作,则将引发AtomicMoveNotSupportedException异常。例如,当目标位置位于不同的FileStore上并且需要复制文件,或者目标位置与此对象关联的提供程序不同。


你能解释一下什么是序列化文件访问吗? - Chris Lang
这意味着在尝试修改时同步文件访问。如果另一个线程有一个打开的文件句柄,当前线程的“删除”操作将无法干净地完成,并且随后的“Files.move”将失败。 - dancnfoo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接