返回首页
当前位置: 主页 > 网络编程 > Jsp实例教程 >

使用NIO2查看及过滤目录的内容

时间:2015-05-05 21:30来源:知行网www.zhixing123.cn 编辑:麦田守望者

在Java 7以前如何查询目录内容并没有太大的变化。不过NIO.2以后增加了一种新的方式,这个很有必要介绍一下。NIO.2的一个很大的改进是它可以在一次方法调用中完成查看及过滤的操作。这为大多数文件系统相关的查看及过滤操作提供了一种优雅的解决方案。

查看根目录

除非你是使用相对路径,否则你需要知道应用程序在环境中的哪个位置,这样才能定义绝对路径。由于文件系统使用的是分层结构,因此会有多个根目录。为了能正确地定位文件及目录你需要能够列出所有的根目录。我们得求助于FileSystem实例,使用它的getRootDirectories方法,这是Java 6的File.listroots()的一个替代方案。

Iterable<Path> it = FileSystems.getDefault().getRootDirectories();
 
System.out.println("Root file system locations: " + Sets.newHashSet(it));

注意,类sets是来自Google的Guava库的,而不是JDK中的。这里用到它是因为希望能方便地获取到格式化好的根目录的字符串。

输出如下:

Root file system locations: C:\, D:\, E:\, F:\, G:\, H:\, I:\,

查看及过滤目录内容:

使用文件系统的常见任务是查看或者过滤指定目录下的文件。我们可能需要修改,分析或者只是去查看下它们——不管是什么,类java.nio.file.Files总能满足我们的需求。它提供了三种形式的newDirectoryStream方法,并返回DirectoryStream 的对象,我们可以用它来遍历目录的所有条目。这里我们可以看到在避免空指针异常方面,当前版本的IO库和上一版本的有很明显的区别。从下面这个例子可以看出现在列出某个目录下的子文件有多简单:

Path directoryPath = Paths.get("C:", "Program Files/Java/jdk1.7.0_40/src/java/nio/file");
 
if (Files.isDirectory(directoryPath)) {
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
        for (Path path : stream) {
            System.out.println(path);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

注意,这里用到了isDirectory方法,它可以避免产生NotDirectoryException异常。还需要注意到的是try-with-resources结构的使用——DirectoryStream既是AutoCloseable又是Closable的(这意味着它可能需要在某个时间关闭掉),因此使用try-with-resources会很方便。代码的输出结果如下:

...
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\CopyOption.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\DirectoryIteratorException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\DirectoryNotEmptyException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\DirectoryStream.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileAlreadyExistsException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\Files.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileStore.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileSystem.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileSystemAlreadyExistsException.java

为了能统一使用DirectoryStream ,可以使用下面两种机制来进行过滤操作:

  • newDirectoryStream(Path dir, String glob) 使用GLOB过滤

  • newDirectoryStream (Path dir, DirectoryStream.Filterfilter)

    使用 DirectoryStream.Filterfilter过滤

使用GLOB模式过滤

首先我们需要知道什么是GLOB。GLOB模式是遵循特定语法规则的用于匹配的字符串表达式。可以参考这篇文章了解下关于GLOB的更多信息。Files类提供了一个简单的方式来进行GLOB方式的过滤。来看一下下面这个例子。

Path directoryPath = Paths.get("C:", "Program Files/Java/jdk1.7.0_40/src/java/nio/file");
 
if (Files.isDirectory(directoryPath)) {
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath, "File*Exception*")) {
        for (Path path : stream) {
            System.out.println(path);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

输出是:

C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileAlreadyExistsException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileSystemAlreadyExistsException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileSystemException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileSystemLoopException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileSystemNotFoundException.java

使用DirectoryStream.Filter过滤

当手头的任务需要更复杂的过滤选项而不仅仅是简单的文件名匹配时,我们需要实现DirectoryStream.Filter 接口。这是我们目前可用的最强大的过滤选项了,因为有了它我们可以访问到程序的其它部分,同时还可以使用第三方库。下面的例子展示了这么一种场景,它需要使用到两个过滤选项:

  • 文件大小是一个偶数值
  • 执行时间的毫秒值也是偶数
Path directoryPath = Paths.get("C:", "Program Files/Java/jdk1.7.0_40/src/java/nio/file");
DirectoryStream.Filter<Path> filter = new Filter<Path>() {
 
    @Override
    public boolean accept(Path entry) throws IOException {
        long size = Files.readAttributes(entry, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS).size();
        long milis = new Date().getTime();
 
        boolean isSizeEvenNumber = size % 2 == 0;
        boolean isTheTimeRight = milis % 2 == 0;
 
        return isTheTimeRight && isSizeEvenNumber;
    }
};
 
if (Files.isDirectory(directoryPath)) {
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath, filter)) {
        for (Path path : stream) {
            System.out.println(path);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

输出如下:

C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\DirectoryStream.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\FileAlreadyExistsException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\Files.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\NotDirectoryException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\NotLinkException.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\package-info.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\WatchEvent.java
C:\Program Files\Java\jdk1.7.0_40\src\java\nio\file\WatchService.java
------分隔线----------------------------
标签(Tag):Java JAVA实例教程 JAVA基础教程 Java源代码 Java技巧
------分隔线----------------------------
推荐内容
猜你感兴趣
博聚网