Check If a Directory Is Empty in Java – 在Java中检查一个目录是否是空的

最后修改: 2020年 7月 22日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’re going to get familiar with a few ways to find out if a directory is empty or not.

在这个快速教程中,我们将熟悉一些方法来找出一个目录是否为空。

2. Using Files.newDirectoryStream

2.使用Files.newDirectoryStream

As of Java 7, the Files.newDirectoryStream method returns a DirectoryStream<Path> to iterate over all the entries in the directory. So we can use this API to check if the given directory is empty or not:

从Java 7开始,Files.newDirectoryStream方法返回一个DirectoryStream<Path> 来遍历该目录中的所有条目。所以我们可以使用这个API来检查给定目录是否为空。

public boolean isEmpty(Path path) throws IOException {
    if (Files.isDirectory(path)) {
        try (DirectoryStream<Path> directory = Files.newDirectoryStream(path)) {
            return !directory.iterator().hasNext();
        }
    }

    return false;
}

For non-directory inputs, we’ll return false without even trying to load the directory entries:

对于非目录输入,我们将返回false,甚至不尝试加载目录条目。

Path aFile = Paths.get(getClass().getResource("/notDir.txt").toURI());
assertThat(isEmpty(aFile)).isFalse();

On the other hand, if the input is a directory, we’ll try to open a DirectoryStream to that directory. Then we’ll consider the directory as empty if and only if the first hasNext() method call return false. Otherwise, it’s not empty:

另一方面,如果输入是一个目录,我们将尝试打开一个DirectoryStream到该目录。当且仅当第一个hasNext()方法调用返回false时,我们将认为该目录为空。否则,它就不是空的。

Path currentDir = new File("").toPath().toAbsolutePath();
assertThat(isEmpty(currentDir)).isFalse();

The DirectoryStream is a Closeable resource, so we’re wrapping it inside a try-with-resources block. As we might expect, the isEmpty method returns true for empty directories:

DirectoryStream是一个Closeable资源,所以我们把它包装在try-with-resources块内。正如我们所期望的,isEmpty方法对于空目录返回true

Path path = Files.createTempDirectory("baeldung-empty");
assertThat(isEmpty(path)).isTrue();

Here we’re using the Files.createTempDirectory to create an empty and temporary directory.

这里我们使用Files.createTempDirectory来创建一个空的临时目录。

3. Using Files.list

3.使用Files.list

As of JDK 8, the Files.list method uses the Files.newDirectoryStream API internally to expose a Stream<Path>. Each Path is an entry inside the given parent directory. Therefore, we can also use this API for the same purpose:

从JDK 8开始,Files.list方法在内部使用Files.newDirectoryStream API来公开一个Stream<Path>。每个Path都是给定的父目录内的一个条目。因此,我们也可以使用这个API来达到同样的目的。

public boolean isEmpty(Path path) throws IOException {
    if (Files.isDirectory(path)) {
        try (Stream<Path> entries = Files.list(path)) {
            return !entries.findFirst().isPresent();
        }
    }
        
    return false;
}

Again, we’re only touching the first entry using the findFirst method. If the returned Optional is empty, then the directory is empty, too.

同样,我们只使用findFirst方法接触第一个条目。如果返回的Optional是空的,那么该目录也是空的。

The Stream is backed by an I/O resource, so we’re making sure to release it appropriately using a try-with-resources block.

Stream是由一个I/O资源支持的,所以我们要确保使用try-with-resources块来适当地释放它。

4. Inefficient Solutions

4.低效的解决方案

Both Files.list and Files.newDirectoryStream will iterate the directory entries lazily. Therefore, they will work with huge directories very efficiently. However, solutions like this will not work well in this scenario:

无论是Files.list还是Files.newDirectoryStream都会懒散地迭代目录条目。因此,它们将非常有效地处理巨大的目录。然而,像这样的解决方案在这种情况下将不能很好地工作。

public boolean isEmpty(Path path) {
    return path.toFile().listFiles().length == 0;
}

This will eagerly load all the entries inside the directory which will be pretty inefficient when dealing with huge directories.

这将急于加载目录中的所有条目,在处理巨大的目录时,效率会相当低。

5. Conclusion

5.总结

In this short tutorial, we got familiar with a few efficient ways to check whether a directory is empty or not.

在这个简短的教程中,我们熟悉了一些有效的方法来检查一个目录是否为空。

As usual, all the examples are available over on GitHub.

像往常一样,所有的例子都可以在GitHub上找到