Java统计目录大小推荐用Files.walk(JDK 8+):先校验路径存在且为目录,再用Stream过滤普通文件、捕获IOException获取大小并累加;兼容旧版可用File递归,需判空、判文件、异常处理。

Java 中递归统计整个目录大小,核心是遍历所有子文件和子目录,累加每个文件的长度(File.length()),跳过目录本身(目录的 length() 返回 0)。需注意符号链接、权限异常、循环引用等边界情况,但基础实现简洁可靠。
使用 File API 递归遍历(JDK 7 之前兼容)
适合对兼容性有要求或项目未升级到较新 JDK 的场景。关键点:判空、判文件、递归调用、异常捕获。
- 先检查
file != null和file.exists(),避免空指针或不存在路径干扰 - 用
file.isFile()判断是否为普通文件,只对文件调用length() - 若为目录,获取其子路径数组(
file.listFiles()),对每个非 null 子项递归处理 - 必须捕获
SecurityException(如无读权限)和NullPointerException(listFiles()在某些情况下返回 null)
使用 Files.walk()(推荐,JDK 8+)
更简洁、函数式、自动处理符号链接(默认不跟随),且支持流式控制(如限制深度、过滤跳过)。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 调用
Files.walk(path)返回Stream<path></path>,用filter(Files::isRegularFile)筛出普通文件 - 用
mapToLong获取每个文件大小:p -> Files.size(p),再sum()累加 - 注意:
Files.size()可能抛IOException,需包裹在 try-catch 或用try-with-resources+forEach手动处理 - 若需跟随符号链接,改用
Files.walk(path, FileVisitOption.FOLLOW_LINKS)
处理大目录与性能注意事项
深层嵌套或海量小文件时,递归调用栈或 Stream 缓存可能引发问题,建议主动优化:
立即学习“Java免费学习笔记(深入)”;
- 避免在递归方法中频繁字符串拼接路径,优先复用
Path对象 - 不用
listFiles()返回数组(内存占用高),可改用Files.newDirectoryStream()迭代器式遍历 - 对超大目录,考虑加超时控制或分块统计(如按子目录并行,用
parallel()需谨慎——IO 密集型不一定加速) - 统计结果建议用
long(单位字节),避免 int 溢出;显示时可转为 KB/MB,用String.format("%.2f MB", size / 1024.0 / 1024.0)
一个安全可用的 Files.walk 示例
兼顾异常处理与可读性:
public static long getDirSize(Path root) throws IOException {
if (!Files.exists(root) || !Files.isDirectory(root)) {
return 0L;
}
try (Stream<Path> stream = Files.walk(root)) {
return stream
.filter(Files::isRegularFile)
.mapToLong(path -> {
try {
return Files.size(path);
} catch (IOException e) {
return 0L; // 跳过无法读取的文件,不中断整体统计
}
})
.sum();
}
}

















