遍历目录做相关处理用法,起始就是在遍历目录的时候提供了一个访问接口的实现,里面预制了四个方法对应不同的处理时刻,这里创建了
SimpleFileVisitor实现了接口中需要的方法
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { if (directory.equals(dir)) { // The top directory should always be listed return FileVisitResult.CONTINUE; } String directoryName = dir.getFileName().toString(); if (!recursiveDirectorySearch || directoryName.startsWith(".") || ignorePattern.matcher(directoryName).matches()) { return FileVisitResult.SKIP_SUBTREE; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path candidate, BasicFileAttributes attrs) throws IOException { String fileName = candidate.getFileName().toString(); if (!fileName.endsWith(completedSuffix) && !fileName.startsWith(".") && includePattern.matcher(fileName).matches() && !ignorePattern.matcher(fileName).matches()) { candidateFiles.add(candidate.toFile()); } return FileVisitResult.CONTINUE; } });
这个静态方法的在FILE里的实现,就是访问者模式的典型应用
public static Path walkFileTree(Path start, Set<FileVisitOption> options, int maxDepth, FileVisitor<? super Path> visitor) throws IOException { /** * Create a FileTreeWalker to walk the file tree, invoking the visitor * for each event. */ try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) { FileTreeWalker.Event ev = walker.walk(start); do { FileVisitResult result; switch (ev.type()) { case ENTRY : IOException ioe = ev.ioeException(); if (ioe == null) { assert ev.attributes() != null; result = visitor.visitFile(ev.file(), ev.attributes()); } else { result = visitor.visitFileFailed(ev.file(), ioe); } break; case START_DIRECTORY : result = visitor.preVisitDirectory(ev.file(), ev.attributes()); // if SKIP_SIBLINGS and SKIP_SUBTREE is returned then // there shouldn't be any more events for the current // directory. if (result == FileVisitResult.SKIP_SUBTREE || result == FileVisitResult.SKIP_SIBLINGS) walker.pop(); break; case END_DIRECTORY : result = visitor.postVisitDirectory(ev.file(), ev.ioeException()); // SKIP_SIBLINGS is a no-op for postVisitDirectory if (result == FileVisitResult.SKIP_SIBLINGS) result = FileVisitResult.CONTINUE; break; default : throw new AssertionError("Should not get here"); } if (Objects.requireNonNull(result) != FileVisitResult.CONTINUE) { if (result == FileVisitResult.TERMINATE) { break; } else if (result == FileVisitResult.SKIP_SIBLINGS) { walker.skipRemainingSiblings(); } } ev = walker.next(); } while (ev != null); } return start; }
对于每个FileTreeWalker又包含了如下
访问的具体实现
stack.push(new DirectoryNode(entry, attrs.fileKey(), stream));
private Event visit(Path entry, boolean ignoreSecurityException, boolean canUseCached) { // need the file attributes BasicFileAttributes attrs; try { attrs = getAttributes(entry, canUseCached); } catch (IOException ioe) { return new Event(EventType.ENTRY, entry, ioe); } catch (SecurityException se) { if (ignoreSecurityException) return null; throw se; } // at maximum depth or file is not a directory int depth = stack.size(); if (depth >= maxDepth || !attrs.isDirectory()) { return new Event(EventType.ENTRY, entry, attrs); } // check for cycles when following links if (followLinks && wouldLoop(entry, attrs.fileKey())) { return new Event(EventType.ENTRY, entry, new FileSystemLoopException(entry.toString())); } // file is a directory, attempt to open it DirectoryStream<Path> stream = null; try { stream = Files.newDirectoryStream(entry); } catch (IOException ioe) { return new Event(EventType.ENTRY, entry, ioe); } catch (SecurityException se) { if (ignoreSecurityException) return null; throw se; } // push a directory node to the stack and return an event stack.push(new DirectoryNode(entry, attrs.fileKey(), stream)); return new Event(EventType.START_DIRECTORY, entry, attrs); }
这里的注释感觉就说的很明白了
Walks a file tree, generating a sequence of events corresponding to the filesin the tree. Path top = ... Set<FileVisitOption> options = ... int maxDepth = ... try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) { FileTreeWalker.Event ev = walker.walk(top); do { process(ev); ev = walker.next(); } while (ev != null); } }