20.4.3 为路径和文件系统操作使用NIO(4)
3. 使用walkFileTree()列出目录树
前面的例子只获取单个目录的内容。然而,有时会希望获取目录树中的文件列表。在过去,这项工作很繁杂,但NIO.2使完成这项工作变得容易,因为现在可以使用File类定义的walkFileTree()方法来处理目录树。该方法有两种形式,在本章中使用的形式如下所示:
- static Path walkFileTree(Path root, FileVisitor<? extends Path> fv)
- throws IOException
对于要遍历的目录,起始位置的路径是由root传递的。fv传递FileVisitor实例。FileVisitor的实现决定了如何遍历目录树,并且支持访问目录信息。如果发生I/O错误,会抛出IOException异常,也可能抛出SecurityException异常。
FileVisitor是定义遍历目录时访问文件方式的接口。FileVisitor是泛型接口,其声明如下所示:
- interface FileVisitor<T>
为了能在walkFileTree()中使用,T需要是Path类型(或派生自Path的任意类型)。FileVisitor接口定义了表20-12中所示的方法。
表20-12 FileVisitor接口定义的方法
- CONTINUE SKIP_SIBLINGS SKIP_SUBTREE TERMINATE
通常,为了继续遍历目录和子目录,方法应当返回CONTINUE。对于preVisitDirectory(),为了绕过目录及其兄弟目录并阻止调用postVisitDirectory()方法,会返回SKIP_SIBLINGS;为了只绕过目录及其子目录,返回SKIP_SUBTREE;为了停止目录遍历,返回TERMINATE。
尽管完全可以通过实现FileVisitor定义的这些方法来创建自己的访问器,但是通常不会这么做,因为SimpleFileVisitor已经提供了一个简单实现。可以只重写感兴趣方法的默认实现。下面的简单示例演示了这个过程。该例显示目录中以“\MyDir”作为根目录的所有文件。注意这个程序是多么简短!
下面是当在前面显示的相同的MyDir目录下执行程序时生成的样本输出。在这个例子中,子目录examples包含文件MyProgram.java。
|
在这个程序中,MyFileVisitor扩展了SimpleFileVisitor,并且只重写了visitFile()方法。在这个例子中,visitFile()方法简单地显示文件,但是更复杂的功能也很容易实现。例如,可以过滤文件或对文件执行操作,比如将它们复制到备份设备。为了清晰起见,使用命名的类重写visitFile()方法,但是也可以使用匿名的内部类。
最后一点:可以使用java.nio.file.WatchService来观察目录的变化。