1. 概述

在本文中,我们将介绍几种简单高效的方式来判断一个目录是否为空。这在文件处理、资源清理或启动校验等场景中非常实用,属于那种“小功能但容易踩坑”的典型问题。

核心目标是:✅ 高效 ✅ 安全 ✅ 兼容 Java 7+

2. 使用 Files.newDirectoryStream

从 Java 7 开始,Files.newDirectoryStream 方法提供了一种低开销的方式来遍历目录内容。它返回一个 DirectoryStream<Path>,支持逐个读取目录条目,不会一次性加载所有文件,非常适合大目录场景。

关键点:

  • ✅ 惰性加载,性能好
  • ✅ 实现了 Closeable,必须用 try-with-resources 管理资源
  • ❌ 不要手动调用 iterator().next(),否则可能抛异常
public boolean isEmpty(Path path) throws IOException {
    if (Files.isDirectory(path)) {
        try (DirectoryStream<Path> directory = Files.newDirectoryStream(path)) {
            return !directory.iterator().hasNext();
        }
    }
    return false;
}

示例测试

判断非目录文件,应返回 false

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

判断当前项目根目录(通常非空):

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

创建临时空目录并验证:

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

⚠️ 注意:Files.createTempDirectory 会在系统临时目录下创建一个空目录,适合用于测试。

3. 使用 Files.list

从 JDK 8 开始,Files.list 方法基于 newDirectoryStream 封装了 Stream API,使用更符合现代 Java 风格。

优势:

  • ✅ 返回 Stream<Path>,可与 Lambda 配合使用
  • ✅ 内部仍为惰性加载
  • ✅ 资源自动管理(配合 try-with-resources)
public boolean isEmpty(Path path) throws IOException {
    if (Files.isDirectory(path)) {
        try (Stream<Path> entries = Files.list(path)) {
            return !entries.findFirst().isPresent();
        }
    }
    return false;
}

关键细节

  • findFirst() 只取第一个元素,不会遍历整个目录
  • 返回 Optional<Path>,用 isPresent() 判断是否存在
  • Stream 背后是 I/O 资源,必须关闭,否则可能引发文件句柄泄漏

4. 不推荐的低效方案

虽然以下写法看起来更“直观”,但在处理大目录时性能极差,属于典型的“简单粗暴但踩坑”写法:

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

问题分析

  • listFiles()一次性加载所有文件到内存
  • ❌ 对于包含数万文件的目录,可能引发 OutOfMemoryError
  • ❌ 已被现代 NIO.2 API 淘汰

✅ 正确做法:始终优先使用 Files 工具类,避免退回 File 旧 API。

5. 总结

方法 Java 版本 是否推荐 说明
Files.newDirectoryStream 7+ 最基础高效,推荐
Files.list 8+ ✅✅ 更现代,推荐
File.listFiles() 旧版 易出问题,不推荐

✅ 推荐选择:

  • 若使用 Java 8+,优先用 Files.list
  • 若需兼容 Java 7,使用 Files.newDirectoryStream

所有示例代码均已上传至 GitHub:

https://github.com/baeldung/core-java-modules/tree/master/core-java-io-3


原始标题:Check If a Directory Is Empty in Java