Anonymous
Anonymous

Reputation: 89

Not able to replace existing directory

I am trying to move folder 114229494 from one path to another and I want to replace the existing folder at the destination path (D:\SampleP2) but I am getting DirectoryNotEmptyException with the code mentioned below.

Since I don't want to change the name of the folder I mentioned D:\SampleP2\114229494 this as destination path There are some images inside the folder.

Please help me to figure out what is wrong with this code.

     public class MoveFiles {
           private String source_path= "D:\\sampleP1\\114229494";
           private String destination_path= "D:\\SampleP2\\114229494";
             public void movefolder() {

              File source = new File(source_path);
              File destination = new File(destination_path);

              Path path1 = FileSystems.getDefault().getPath(source_path);
              Path path2 = FileSystems.getDefault().getPath(destination_path);


              System.out.println(source);
              System.out.println(destination);
              try {
                    Files.move(path1, path2, StandardCopyOption.REPLACE_EXISTING);
              } catch (IOException e) {
              e.printStackTrace();
                    System.out.println("there is file in uploads");
              }
          }
      }
    

Upvotes: 1

Views: 459

Answers (1)

DuncG
DuncG

Reputation: 15126

If path1 is a directory and path2 exists already you cannot use Files.move(path1, path2) nor Files.move(path1, path2, StandardCopyOption.REPLACE_EXISTING) as these give rise to either FileAlreadyExistsException or DirectoryNotEmptyException.

A reliable move operation for occasions where the destination directory exists already needs to traverse the source directory tree and move each file to the same location under the destination, cleaning up folders as they are emptied.

The Files.walkFileTree method handles traversals, add a suitable FileVisitor action to move / merge the path1=>path2 files:

public static void move(final Path source, final Path dest) throws IOException {
    FileVisitor<Path> visitor = new FileVisitor<>() {
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
            final Path target = dest.resolve(source.relativize(dir));
            System.out.println("Files.createDirectories("+target+")");
            Files.createDirectories(target);
            return FileVisitResult.CONTINUE;
        }
        public FileVisitResult visitFile(Path p, BasicFileAttributes attrs) throws IOException {
            final Path targ = dest.resolve(source.relativize(p));
            System.out.println("Files.move("+p+", "+targ+", StandardCopyOption.REPLACE_EXISTING)");
            Files.move(p, targ, StandardCopyOption.REPLACE_EXISTING);
            return FileVisitResult.CONTINUE;
        }
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            // Dir should be empty by now or there is coding error:
            System.out.println("Files.deleteIfExists("+dir+")");
            if (!Files.deleteIfExists(dir))
                throw new IOException("Failed to delete src dir: "+dir);
            return FileVisitResult.CONTINUE;
        }
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
            throw  exc;
        }
    };
    Files.walkFileTree(source, visitor);
}

Note that the above works for files or folders - Files.walkFileTree handles calling the appropriate callbacks.

The logic of the above move could be made significantly quicker if you use File.move(subdir,targsubdir) if detecting that a subdir is not found in the target - replacing createDirectories / deleteIfExists. That would avoid need to move every file underneath that tree. However I will leave that as an exercise for the reader.

Upvotes: 2

Related Questions