首页 > 编程笔记 > Java笔记

访问者模式在JDK源码中的应用

在早期的 Java 版本中,如果要对指定目录下的文件进行遍历,必须用递归的方式来实现,这种方法复杂且灵活性不高。

Java 7 版本后,Files 类提供了 walkFileTree() 方法,该方法可以很容易的对目录下的所有文件进行遍历,需要 Path、FileVisitor 两个参数。其中,Path 是要遍历文件的路径,FileVisitor 则可以看成一个文件访问器。源码如下。
  1. package java.nio.file;
  2. public final class Files {
  3. ...
  4. public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
  5. throws IOException
  6. {
  7. return walkFileTree(start,
  8. EnumSet.noneOf(FileVisitOption.class),
  9. Integer.MAX_VALUE,
  10. visitor);
  11. }
  12. ...
  13. }
FileVisitor 提供了递归遍历文件树的支持,这个接口的方法表示了遍历过程中的关键过程,允许在文件被访问、目录将被访问、目录已被访问、发生错误等过程中进行控制。换句话说,这个接口在文件被访问前、访问中和访问后,以及产生错误的时候都有相应的钩子程序进行处理。

FileVisitor 主要提供了 4 个方法,且返回结果的都是 FileVisitResult 对象值,用于决定当前操作完成后接下来该如何处理。FileVisitResult 是一个枚举类,代表返回之后的一些后续操作。源码如下。
  1. package java.nio.file;
  2.  
  3. import java.nio.file.attribute.BasicFileAttributes;
  4. import java.io.IOException;
  5. public interface FileVisitor<T> {
  6. FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  7. throws IOException;
  8. FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  9. throws IOException;
  10. FileVisitResult visitFileFailed(T file, IOException exc)
  11. throws IOException;
  12. FileVisitResult postVisitDirectory(T dir, IOException exc)
  13. throws IOException;
  14. }
  15.  
  16. package java.nio.file;
  17.  
  18. public enum FileVisitResult {
  19. CONTINUE,
  20. TERMINATE,
  21. SKIP_SUBTREE,
  22. SKIP_SIBLINGS;
  23. }
FileVisitResult 主要包含 4 个常见的操作。
通过访问者去遍历文件树会比较方便,比如查找文件夹内符合某个条件的文件或者某一天内所创建的文件,这个类中都提供了相对应的方法。它的实现也非常简单,代码如下。
  1. public class SimpleFileVisitor<T> implements FileVisitor<T> {
  2. protected SimpleFileVisitor() {
  3. }
  4.  
  5. @Override
  6. public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  7. throws IOException
  8. {
  9. Objects.requireNonNull(dir);
  10. Objects.requireNonNull(attrs);
  11. return FileVisitResult.CONTINUE;
  12. }
  13.  
  14. @Override
  15. public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  16. throws IOException
  17. {
  18. Objects.requireNonNull(file);
  19. Objects.requireNonNull(attrs);
  20. return FileVisitResult.CONTINUE;
  21. }
  22.  
  23. @Override
  24. public FileVisitResult visitFileFailed(T file, IOException exc)
  25. throws IOException
  26. {
  27. Objects.requireNonNull(file);
  28. throw exc;
  29. }
  30.  
  31. @Override
  32. public FileVisitResult postVisitDirectory(T dir, IOException exc)
  33. throws IOException
  34. {
  35. Objects.requireNonNull(dir);
  36. if (exc != null)
  37. throw exc;
  38. return FileVisitResult.CONTINUE;
  39. }
  40. }

所有教程

优秀文章