清单 2. FileVisitor 输出
I'm about to visit the headDir\mySubDirectory2 directory
I'm about to visit the headDir\mySubDirectory2\mySubDirectory3 directory
I'm visiting file headDir\mySubDirectory2\mySubDirectory3\myFile4 which has size 2
I'm visiting file headDir\mySubDirectory2\myFile3 which has size 2
I'm about to visit the headDir\mySubDirectory1 directory
I'm visiting file headDir\mySubDirectory1\myFile2 which has size 2
I'm visiting file headDir\myFile1 which has size 2
正如您所见到的,该文件是深度优先遍历,但不一定在任何目录内按字母顺序来进行。回调方法如期望那样被调用,我们可以看到,树中的所有文件都已列出,并且所有目录均已被访问。
仅利用 15 行内容,我们就创建了文件访问程序,来浏览任何您所给出的文件树,并检查包含在其中的文件。这个例子很基础,但是回调可按需地进行更加复杂的实现。
目录监视
第二个例子展示了新 WatchService API 及其相关类的精彩世界。
这一例子的场景很简单:您想要追踪特定目录(或多个目录)中是否有文件或者目录正被创建、修改、或者删除。您可能要利用这一信息来更新 GUI 显示中列示的文件,或者想检查对将要重新加载的配置文件的修改。在以前的 Java 版本中,必须实现一个代理,该代理运行在单独的线程中,来保持对目录所有内容的追踪,不断轮询文件系统来查看是否有相关的情况发生。在 Java 7 中,WatchService API 提供了查看目录的能力。这就免除了自己编写文件系统轮询程序的所有麻烦,并且,如果可能的话,它可基于本地系统 API 来获取更优的性能。
第一步是通过 java.nio.file.FileSystems 类创建 WatchService 实例。本文不涉及文件系统的细节,因此在大多数情况下,您 会希望得到默认的文件系统,然后调用其 newWatchService() 方法:
现在我们有了自己的监视服务实例,我们想要注册到一个路径来进行监视。因为我们想要以与文件访问程序示例完全不同的方式,来为监视的目录创建一个 Path 对象,所以,我们可以在此使用其 File 实例:
Path watchDirPath = watchDirFile.toPath();
Path 类实现 java.nio.file.Watchable 接口,并且该接口定义我们将在这里例子中使用的 register() 方法。WatchKey register(WatchService watchService, WatchEvent.Kind... events) 通过为所给特定事件所指定的 watchService 来注册这一方法所要调用的 Path。仅当在注册调用中指定了事件时,事件才会触发一个通知。
对于默认的 WatchService 实现,java.nio.file.StandardWatchEventKind 类定义三个 java.nio.file.StandardWatchEventKind 的静态实现,这些可用于 register() 调用: