Files.move and Files.copy is throwing java.nio.file.FileAlreadyExistsException

aga picture aga · Jun 9, 2016 · Viewed 20.4k times · Source

I want to delete one file and rename another file with the old file but I am not able to move this file as java is throwing java.nio.file.FileAlreadyExistsException Following is the code snippet I am using

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;
        }
    }

Here is the exception I am recieving enter image description here on Files.move(tempPath, tempPath.resolveSibling(origFileName), StandardCopyOption.REPLACE_EXISTING);

Also when I see this file in windows explorer, its thumbnail is present but cannot able to open it. I am not able to understand why it is happening and If I am using REPLACE_EXISTING, why it is throwing FileAlreadyExistsException exception.

Also I edited the previous question as it is not clearly stated.

Please help.

Anuj

Answer

dancnfoo picture dancnfoo · Apr 28, 2017

Check if you have another thread holding on to the same file resource while running Files.move or Files.copy. I had the same exception and file access symptom and was able to resolve it after serializing the file accesses.

Also, by using the REPLACE_EXISTING option when doing Files.copy or Files.move, you no longer need to code the multiple steps of deleting the original file and then renaming the tmp, although Files.move or Files.copy are not guaranteed atomic. There is a ATOMIC_MOVE option, however I don't like the implementation specific guarantee where IOException could be thrown if a file exists already as described by the javadoc.

ATOMIC_MOVE : The move is performed as an atomic file system operation and all other options are ignored. If the target file exists then it is implementation specific if the existing file is replaced or this method fails by throwing an IOException. If the move cannot be performed as an atomic file system operation then AtomicMoveNotSupportedException is thrown. This can arise, for example, when the target location is on a different FileStore and would require that the file be copied, or target location is associated with a different provider to this object.