推荐用 files.walk() 流式统计:先 count() 得文件数,再 sum() 得总大小,两行代码简洁高效,自动跳过目录和符号链接,异常时返回0,兼容java 8且内存友好。

Java 中统计指定目录下所有文件的总大小和数量,推荐使用 Files.walk() 配合流式处理,简洁高效且能自动处理嵌套子目录、符号链接(可选)和异常情况。
用 Files.walk() 一行流式统计
这是最常用也最推荐的方式,代码简短、逻辑清晰、支持并行(必要时):
Path root = Paths.get("/your/target/dir");
try {
long[] result = Files.walk(root)
.filter(Files::isRegularFile)
.mapToLong(path -> {
try {
return Files.size(path);
} catch (IOException e) {
return 0; // 或记录日志,跳过无法读取的文件
}
})
.summaryStatistics();
long totalCount = result[0]; // 实际需额外计数——见下方修正
long totalSize = result[1];
} catch (IOException e) {
e.printStackTrace();
}
⚠️ 注意:summaryStatistics() 只提供 size 统计,不提供 count。更稳妥的做法是用 Collectors.counting() 和 summingLong() 同时收集:
- 用
Collectors.teeing()(Java 12+)可一次遍历完成两个统计 - Java 8–11 推荐分两次流操作(开销极小,因
Files.walk()是惰性求值)
Java 8 兼容写法(推荐)
兼顾可读性与兼容性,两行搞定:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
Path root = Paths.get("/path/to/dir");
long fileCount = Files.walk(root)
.filter(Files::isRegularFile)
.count();
long totalSize = Files.walk(root)
.filter(Files::isRegularFile)
.mapToLong(path -> {
try { return Files.size(path); }
catch (IOException e) { return 0L; }
})
.sum();
✅ 优点:无需额外依赖,自动跳过目录、快捷方式、权限不足的文件(捕获 IOException);Files.walk() 默认不跟随符号链接,安全。
需要排除特定路径或按扩展名过滤?
直接在 filter() 中叠加条件即可:
- 跳过临时文件:
.filter(p -> !p.toString().endsWith(".tmp")) - 只统计图片:
.filter(p -> Set.of(".jpg", ".png", ".gif").contains( FileUtils.getExtension(p.toString()).toLowerCase()))(需自行实现或用 Apache Commons IO) - 排除某个子目录:
.filter(p -> !p.startsWith(root.resolve("node_modules")))
大目录性能与内存注意点
对海量小文件(如数十万),Files.walk() 是懒加载,内存友好;但若中途需中断或监控进度,可改用 SimpleFileVisitor 手动遍历:
- 重写
visitFile()累加计数与大小 - 在
visitFileFailed()中处理权限异常 - 适合需要精细控制(如限速、暂停、实时回调)的场景
普通统计任务无需这么复杂,流式方案足够快且不易出错。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










