📜 ⬆️ ⬇️

Parsing the Files.walkFileTree () utility;

Not finding anywhere sensible description in Russian, that for the beast Files.walkFileTree () , and with a creak having mastered it, as it turned out later, simple functionality, I decided to share in the framework of fixing material with examples, which I missed so much.

The walkFileTree () method allows you to bypass the tree of files and subdirectories passed to it as a parameter of the Path element ...

Two method signatures

Files.walkFileTree(Path start, FileVisitor<? super Path> visitor); Files.walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor); 

Where
Path start - directory, the contents of which will be bypassed,
FileVisitor visitor is an instance of the class that implements the FileVisitor interface, or inherits from SimpleFileVisitor (). The latter, in my opinion, is more convenient to use when you do not need to override all FileVisitor () methods, which will be discussed below (but everything depends on the situation),
Set <\ FileVisitOption> options - a set of options that determine the behavior when traversing,
maxDepth - the depth of the subdirectories.

First, about the parameters that sooner or later come in handy.

maxDepth - traversal depth. At = 0, the directory will not be entered, at = MAX_VALUE the directory will be studied to the maximum depth, respectively, at maxDepth = 3, the passage will be carried out on 3 subdirectories "down".

FileVisitOption - enum set, which determines whether the program should follow symbolic links when crawling (in this case, the value FileVisitOption.FOLLOW_LINKS is specified).

FileVisitor is an interface that has 4 methods:

1) FileVisitResult preVisitDirectory (T dir, BasicFileAttributes attrs) throws IOException;
includes a set of methods that should be performed before visiting the current subdirectory. For example, through attrs you can get from such data as:
lastModifiedTime ()
lastAccessTime (),
creationTime (),
isRegularFile () - true if we have a file,
isDirectory () - true if we have a directory
isSymbolicLink () - true if the object is a link,
isOther () is true if the object in question is neither a file, nor a directory, nor a link,
size () - returns the size of the object and
fileKey () - returns the file key or null;

If during the crawling process it is planned to count the number of directories, we should not forget that the start directory will also be taken into account in the total amount.

2) FileVisitResult visitFile (T file, BasicFileAttributes attrs) throws IOException;
a set of methods that should be performed during a visit to the current file (you can, for example, rummage through its contents and search for occurrences of the search string, or again find out the date of the last visit, change the file or fold the size of all files to crawl the directory size)

Example

 public class MyFileVisitor extends SimpleFileVisitor<Path> { String partOfName; String partOfContent; @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { boolean containsName = true; if(partOfName!=null && !file.getFileName().toString().contains(partOfName)) containsName = false; String content = new String(Files.readAllBytes(file)); boolean containsContent = true; if(partOfContent!=null && !content.contains(partOfContent)) containsContent = false; if(containsName && containsContent) foundFiles.add(file); return FileVisitResult.CONTINUE; } 

In this example, when traversing the file tree, each file is checked for the simultaneous execution of 2 events - whether the file name contains the desired entry and whether the body of the file contains the occurrence of the required string. When both conditions are met, the file is added to the result sheet, after which the crawl continues;

Or another example of overloading the visitFile method.

 @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { if(path.toString().endsWith(".rar") || path.toString().endsWith(".zip")) archived.add(path.toString()); return FileVisitResult.CONTINUE; } 

The program during a tree traversal when visiting a file, in case it is a zip or rar archive, adds its address (path) as a string to the list of archive files;

3) FileVisitResult visitFileFailed (T file, IOException exc) throws IOException;
This method can be useful in case of file access error + it “can” throw Exception. The rest can be taught through the Override annotation. For example, count the number of files that could not be accessed;

Example

 @Override public FileVisitResult visitFileFailed(Path path, IOException exc) throws IOException { failed.add(path.toString()); return FileVisitResult.SKIP_SUBTREE; } 

In the case of an unsuccessful attempt to access the path, the given path as a string is added to the failed sheet for it like it, and the program continues bypassing without visiting its subdirectory;

4) FileVisitResult postVisitDirectory (T dir, IOException exc) throws IOException;
Everything that needs to be done after visiting the directory should be listed as part of the overload of this method. For example, having gone through the directory and destroying all the files in it, this method can also destroy it itself (we remember that Files.delete (Path dir) only deletes the directory if it is empty and does not contain any files).

Example

 @Override public FileVisitResult postVisitDirectory(Path path, IOException exc) throws IOException { Files.delete(path); return FileVisitResult.CONTINUE; } 

All the above methods finish working, returning the “visit results” (FileVisitResult) of an object that belong to the enum set and can take the following values:

  1. CONTINUE - continues to traverse the tree;
  2. TERMINATE - finishes tree traversal;
  3. SKIP_SUBTREE - continues traversing, without entering this directory;
  4. SKIP_SIBLINGS - excludes from bypassing the "relatives" of the file or directory;

Source: https://habr.com/ru/post/437694/