it_worker365

   ::  ::  ::  ::  :: 管理

遍历目录做相关处理用法,起始就是在遍历目录的时候提供了一个访问接口的实现,里面预制了四个方法对应不同的处理时刻,这里创建了

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);
     }
 }

 

posted on 2018-11-01 11:21  it_worker365  阅读(136)  评论(0编辑  收藏  举报