If we want to search for all files in a given directory named Dir2 folder there is an issue.Dir2 will be considered the root of file tree ,so it will only search all files that are directly under Dir2. If there is directory named DIr3 inside Dir2 so we will not be able to search any files that are in Dir3 directory.
Same way if we want to copy files from Dir2 it will never copy files that are one level down i.e it will only copy files that are under Dir2 like File1.txt etc and not any files under Dir3 etc
So if we want to access or copy all files that are in a directory within a directory ee have to walk down the file tree to that directory like Dir3 etc.
To walk down the file tree we need to use FileVisitorInterface.
Using this interface we can run code at each stage of traversal process.
Some methods of this interface are
preVisitDirectory() -This method accepts reference to the directory and the basicAttributes instance for the directory.It is called before entries in the directory are visited.
postVisitDirectory() -This method accepts reference to the directory and an exception object(when necessary.It is called after entries in the directory and all its descendants are visited.The exception parameters will be set when an exception happens during the traversal of the entries and the descendants. There a way to skip files as you are traversing so not every file has to have been visited for this method to be called. Every file has to be visited or explicitly skipped. Of course if an exception is thrown and not handled. The traversal will prematurely end and postVisitDirectory will be called.
visitFile() - This method accepts a reference to the file and a BasicAttributes instance. This is where you run the code that will operate on the file. Its only called for files.
4.visitFileFailed() - This method is called when a file can't be accessed . The exception that is thrown is passed to the method. We can decide what to do with it (throw it ,print it or anything else that makes sense for the application and operation being performed. Can be called for files and directories)
So for all the above methods we will simply extend a class called SimpleFileVisitor that implements FileVisitor Interface. so we can use some of the methods of this class SimpleFileVisitor to transver through all directories of Dir2 and print all the contents of each sub directory as we go
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
//Please note when extending SimpleFileVisitor we are specifying it as of type Path
//So the methods we will be extending will also have first parameter as of type Path
public class PrintNames extends SimpleFileVisitor<Path> {
//Now let us override visitFile method
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//Here wew are printing the complete filepath
System.out.println(file.toAbsolutePath());
return FileVisitResult.CONTINUE;
}
//Now let us override preVisitDirectory and postVisitDirectory as well
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println(dir.toAbsolutePath());
return FileVisitResult.CONTINUE; }
//if we don't implement the visitFileFailed method and an error occurs then IOEXception will be thrown
// But we can actually notify the user and continue the traversal using the below method.
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
System.out.println("Error access file :"+file.toAbsolutePath()+ " "+exc.getMessage());
return FileVisitResult.CONTINUE;
}
}
Now in a seperate class in the main method we can make a patj object to the directory from which we want to transverse all the contents
public static void main(String[] args) {
Path dir2Path = FileSystems.getDefault().getPath("FileTree1"+File.separator+"Dir2");
try{
Files.walkFileTree(dir2Path,new PrintNames());
}
catch (IOException e){
System.out.println(e.getMessage());
}