Searching for a file by name

Searching a certain file on a computer is a common task. Typically, we rely on tools that are provided by the operating system or additional tools, but if we want to accomplish this programmatically (for example, we may want to write a file search tool with special features), then FileVisitor can help us achieve this in a pretty straightforward way. The stub of this application is listed as follows:

public class SearchFileVisitor implements FileVisitor {

private final Path fileNameToSearch;
private boolean fileFound;
...

private boolean search(Path file) throws IOException {

Path fileName = file.getFileName();

if (fileNameToSearch.equals(fileName)) {
System.out.println("Searched file was found: " +
fileNameToSearch + " in " + file.toRealPath().toString());

return true;
}

return false;
}
}

Let's take a look at the main checkpoints and the implementation of searching a file by name:

  • visitFile() is our main checkpoint. Once we have control, we can query the currently visited file for its name, extension, attributes, and so on. This information is needed in order to draw a comparison with the same information on the searched file. For example, we compare the names, and at first match, we TERMINATE the search. But if we search for more such files (if we know that there is more than one), then we can return CONTINUE:
@Override
public FileVisitResult visitFile(
Object file, BasicFileAttributes attrs) throws IOException {

fileFound = search((Path) file);

if (!fileFound) {
return FileVisitResult.CONTINUE;
} else {
return FileVisitResult.TERMINATE;
}
}
The visitFile() method cannot be used for finding folders. Use the preVisitDirectory() or postVisitDirectory() methods instead.
  • visitFileFailed() is the second important checkpoint. When this method is invoked, we know that something went wrong while visiting the current file. We prefer to ignore any such issues and CONTINUE the search. It's pointless to stop the search process:
@Override
public FileVisitResult visitFileFailed(
Object file, IOException ioe) throws IOException {
return FileVisitResult.CONTINUE;
}

The preVisitDirectory() and postVisitDirectory() methods don't carry any important tasks, so we can skip them for brevity.

In order to start the search, we rely on another flavor of the Files.walkFileTree() method. This time, we specify the start point of the search (for example, all roots), the options that were used during searching (for example, follow symbolic links), the maximum number of directory levels to visit (for example, Integer.MAX_VALUE), and the FileVisitor (for example, SearchFileVisitor):

Path searchFile = Paths.get("JavaModernChallenge.pdf");

SearchFileVisitor searchFileVisitor
= new SearchFileVisitor(searchFile);

EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
Iterable<Path> roots = FileSystems.getDefault().getRootDirectories();

for (Path root: roots) {
if (!searchFileVisitor.isFileFound()) {
Files.walkFileTree(root, opts,
Integer.MAX_VALUE, searchFileVisitor);
}
}

If you take a look at the code that's bundled with this book, the preceding search traverses all the roots (directories) of your computer in a recursive approach. The preceding example can be easily adapted for searching by extension, by a pattern, or to look inside files from some text.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.154.64