列出和过滤NIO.2中的目录内容

在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类不是JDK的一部分,而是来自Google的Guava库。 我在这里使用它只是为了方便获得根目录的格式正确的字符串表示形式。

具有以下输出:

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

列出和过滤目录内容

使用文件系统时,标准任务是列出或过滤给定目录中的文件。 我们可能需要修改,分析或简单列出它们-无论java.nio.file.Files何种原因,类java.nio.file.Files都有我们的支持。 它提供了newDirectoryStream方法的三种变体,它们返回DirectoryStream<Path>类型的对象,以允许我们遍历目录中的条目。 在这里,我们看到了防止NullPointerException的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构造的使用– DirectoryStreamAutoCloseableCloseable (这意味着它需要在某个时间关闭),因此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<Path>通用可用性,我们可以使用两种基本机制进行过滤:

  • newDirectoryStream(Path dir, String glob)
    • 使用GLOB过滤
  • newDirectoryStream (Path dir, DirectoryStream.Filterfilter)
    • 使用DirectoryStream.Filter过滤
使用GLOB模式过滤

首先,我们需要知道GLOB是什么。 GLOB模式是遵循特定语法规则的字符串表达式,它们用于匹配目的。 请参阅以下文章,以获取有关GLOB和GLOB语法的更多信息。 在使用GLOB进行过滤时, Files类为我们提供了一种简便的方法。 让我们看下面的例子。

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>接口。 这是我们可以使用的最强大的筛选选项,因为我们可以访问应用程序的其余部分,并且可能使用第三方库。 下面的示例使用两种过滤条件显示了这种情况:

  • 文件大小必须为偶数
  • 执行时间(以毫秒为单位)必须为偶数
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

*请注意,根据使用条件,每次执行过滤后的文件可能会有所不同。

翻译自: https://www.javacodegeeks.com/2014/06/listing-and-filtering-directory-contents-in-nio-2.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值