So an example is as below
sourceFolder = "FileTree\Dir2\Dir3\File1.txt";
sourceRoot = "FileTree\Dir2";
targetRoot = "FileTree\Dir4\DirCopy;
relativizedPath = sourceRoot.relativize(sourcePath); which will be "Dir3\File1.txt"
relativizedPathForCopy = targetRoot.resolve(relativizedPath); which will be "FileTree\Dir4\Dir\DirCopy\Dir3\File1.txt
Complete code for a class implementing SimpleFileVisitor class is below. We will use this class to copy complete of a directory from one place to another
public class CopyFiles extends SimpleFileVisitor<Path> {
private Path sourceRoot;
private Path targetRoot;
public CopyFiles(Path sourceRoot, Path targetRoot) {
this.sourceRoot = sourceRoot;
this.targetRoot = targetRoot;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
System.out.println("Error access file :"+file.toAbsolutePath()+ " "+exc.getMessage());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
//To construct the path we use Path.relativize method .This method constructs a relative path which resolves to a given path
//For example if path to relativize against is C:\path1 and given path is C:\path1\path2\path3
// then the relativised path is \path2\path3 which is given path relative to C:\path1
//Now once we got the relative path we then need to resolve it against copied directories locations by calling
//by calling path.resolve method and that will turn the relative path we go from relativised method into the full path for the copied file.
//So over here we are getting relativized path for source directory and target directory
Path relativizedPath = sourceRoot.relativize(dir);
System.out.println("RelativisedPath = "+relativizedPath);
Path copyDir = targetRoot.resolve(relativizedPath);
System.out.println("RelativisedPath = "+copyDir);
try{
//We are then copying the files
Files.copy(dir,copyDir);
}
catch(Exception e ){
e.printStackTrace();
//If an exception occurs we will skip the subtree by using the below line of code i.e we will stop processing files for that subtree
return FileVisitResult.SKIP_SUBTREE;
}
return FileVisitResult.CONTINUE;
}
//Here we override visitFile method
//In this method just as in directory method we use relativised method to find paths for copied files and then we can use copy method to copy those
files.
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//So over here we are getting relativized path to find paths for copied files.
Path relativizedPath = sourceRoot.relativize(file);
System.out.println("RelativisedPath = "+relativizedPath);
Path copyDir = targetRoot.resolve(relativizedPath);
System.out.println("RelativisedPath = "+copyDir);
try{
//We are then copying the files
Files.copy(file,copyDir);
}
catch(Exception e ){
System.out.println(e.getMessage());
}
return FileVisitResult.CONTINUE;
}
}
We can then simply copy the complete contents of a directory in main method of a class using the code below
Path copyPath = FileSystems.getDefault().getPath("FileTree1"+File.separator+"Dir4"+File.separator+"Dir2Copy");
//so path will be like FileTree1\\Dir4\\Dir2Copy
try{
Files.walkFileTree(dir2Path,new CopyFiles(dir2Path,copyPath));
}
catch(Exception e){
System.out.println(e.getMessage());
}