在Java中移动目录会引发java.nio.file.FileAlreadyExistsException

时间:2018-07-20 01:02:45

标签: java windows

我正在创建回滚功能,这是我想要实现的功能:

  1. 在与tmp folder相同的位置创建一个data folder

  2. 在执行任何操作之前,我将所有内容从data folder复制到tmp folder(少量数据)。

  3. 在回滚时,我想删除data folder并将重命名 tmp folder更改为data folder

这是我尝试过的

String contentPath = "c:\\temp\\data";
    String tmpContentPath = "c:\\temp\\data.TMP";
    if (Files.exists(Paths.get(tmpContentPath)) && Files.list(Paths.get(tmpContentPath)).count() > 0) {
        FileUtils.deleteDirectory(new File(contentPath));
        Files.move(Paths.get(tmpContentPath), Paths.get(contentPath), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
    }

但是即使我以相同的方法删除了目标目录,也会抛出FileAlreadyExistsException

程序退出后,我将看不到c:\temp\data目录,因此该目录实际上已被删除。

现在,如果我尝试使用StandardCopyOption.ATOMIC_MOVE,它将引发java.nio.file.AccessDeniedException。

在这种情况下将tmp dir移至data dir的最佳方法是什么?

3 个答案:

答案 0 :(得分:0)

实际上,在Java 7或更高版本中,即使存在冲突,也可以使用Files来实现文件夹的移动,这意味着目标文件夹已经存在。

private static void moveFolder(Path thePath, Path targetPath) {
    if (Files.exists(targetPath)) { // if the target folder exists, delete it first;
        deleteFolder(targetPath);
    }
    try {
        Files.move(thePath, targetPath);
    } catch (IOException ignored) {
        ignored.printStackTrace();
    }
}

private static void deleteFolder(Path path) {
    try {
        if (Files.isRegularFile(path)) { // delete regular file directly;
            Files.delete(path);
            return;
        }
        try (Stream<Path> paths = Files.walk(path)) {
            paths.filter(p -> p.compareTo(path) != 0).forEach(p -> deleteFolder(p)); // delete all the children folders or files;
            Files.delete(path); // delete the folder itself;
        }
    } catch (IOException ignored) {
        ignored.printStackTrace();
    }
}

答案 1 :(得分:0)

Try This
public class MoveFolder
{
public static void main(String[] args) throws IOException
{
    File sourceFolder = new File("c:\\temp\\data.TMP");
    File destinationFolder = new File("c:\\temp\\data");
    if (destinationFolder.exists())
    {
        destinationFolder.delete();
    }
    copyAllData(sourceFolder, destinationFolder);
}
private static void copyAllData(File sourceFolder, File destinationFolder) 
throws IOException
{
       destinationFolder.mkdir();
       String files[] = sourceFolder.list();
       for (String file : files)
        {
            File srcFile = new File(sourceFolder, file);
            File destFile = new File(destinationFolder, file);
            copyAllData(srcFile, destFile);  //call recursive
        }
}
}

答案 2 :(得分:0)

找出问题所在。在执行回滚之前的代码中,我正在执行备份,在该方法中,我正在使用本节进行复制

if (Files.exists(Paths.get(contentPath)) && Files.list(Paths.get(contentPath)).count() > 0) {
        copyPath(Paths.get(contentPath), Paths.get(tmpContentPath));

}

将其更改为

try (Stream<Path> fileList = Files.list(Paths.get(contentPath))) {
        if (Files.exists(Paths.get(contentPath)) && fileList.count() > 0) {
            copyPath(Paths.get(contentPath), Paths.get(tmpContentPath));
        }
    }

解决问题