filepath.walk 可遍历目录并获取文件大小,需正确处理回调函数签名、权限错误、目录过滤及单位换算,避免重复 stat 调用,配合 dry-run 和路径白名单确保安全。

用 filepath.Walk 遍历目录并获取文件大小
Go 标准库没有“按大小筛选文件”的现成函数,得自己走一遍目录树,对每个 os.FileInfo 检查 Size()。关键点是:必须用 filepath.Walk(不是 filepath.WalkDir),因为后者在 Go 1.16+ 才有,且返回的 DirEntry 不直接提供文件大小,还得额外 entry.Info() 调用——反而多一次系统调用,得不偿失。
常见错误是把 filepath.Walk 的回调函数签名写错,漏掉 err 参数,导致无法跳过权限拒绝的子目录(比如 /proc 下某些条目)。
- 回调函数签名必须是
func(path string, info os.FileInfo, err error) error - 遇到
err != nil时,若为os.ErrPermission,应返回nil继续遍历(否则整个 walk 中断) -
info.Size()返回字节数,注意符号:它总是 ≥ 0;对目录返回的是实现定义值(Linux 上通常是 4096,不可靠),所以务必先用info.IsDir()过滤掉目录
按字节、KB 或 MB 精确匹配还是范围过滤?
“特定大小”在实际脚本里往往不是“等于某字节”,而是“大于 X”“小于 Y”或“介于 A 和 B 之间”。硬写 == 容易误删空日志或配置文件。建议默认支持范围,并把单位转换封装好。
例如用户说“清理大于 100MB 的文件”,你不能直接比 info.Size() > 100,得转成字节:100 * 1024 * 1024。更稳妥的做法是解析带单位的输入(如 "100MB"、"512KB"),用 strings.TrimSuffix 和 strings.ToUpper 处理后缀,再查表换算。
- 支持单位:B / KB / MB / GB(不建议支持 TB,容易误操作)
- 避免浮点运算——全部转为
int64字节比较,防止精度丢失 - 如果要“精确等于”,需明确提示风险:“等于 0B 将删除所有空文件,包括 .gitkeep”
安全删除前必须做 dry-run 和路径白名单
真实环境跑 os.Remove 前,90% 的翻车都源于路径拼错或通配符误扩。必须默认开启 dry-run 模式(只打印将删什么,不真删),加 -exec 参数才执行。
在 Golang 中使用 samber/hot 进行内存缓存,支持 LRU、LFU、TinyLFU、W‑TinyLFU、S3FIFO、ARC、TwoQueue、SIEVE、FIFO 等淘汰算法,提供 TTL、缓存加载器及分片功能。
另一个高频坑:没限制搜索根目录,脚本被误放在 / 下运行,递归扫完整个磁盘。解决方案是硬编码白名单或强制校验起始路径是否在允许范围内(比如只允许 /tmp、$HOME/.cache、项目下的 logs/)。
- dry-run 输出格式建议:用
fmt.Printf("%s (%d B) ", absPath, info.Size()),方便 grep 或 wc 统计 - 绝对路径检查:用
filepath.Abs转换输入路径,再用strings.HasPrefix(abs, "/tmp/")类似逻辑拦截非法根目录 - 禁止匹配隐藏文件?加个
strings.HasPrefix(filepath.Base(path), ".")判断(但注意.git目录下可能有大对象,需权衡)
性能敏感场景下避免重复 Stat 调用
如果目录极深、文件极多(比如数百万小文件),filepath.Walk 本身已做了一次 stat,回调里的 info 就是结果。千万别再对同一路径调用 os.Stat(path)——这会触发第二次系统调用,I/O 开销翻倍。
另外,如果后续还要读文件内容(比如按哈希去重),别在 walk 回调里直接 os.Open;应先收集路径列表,walk 完再批量处理,避免阻塞遍历流程。
- 确认你用的是
info.Size(),不是os.Stat(path).Size() - 需要并发处理匹配文件时,用
sync.WaitGroup+ channel 控制 goroutine 数量,别无脑启 1000 个 - Windows 下注意长路径(>260 字符):启用
\?前缀需额外处理,普通脚本建议避开
真正难的不是写 delete 逻辑,而是判断“这个文件到底能不能删”——日志轮转机制、进程是否正在写入、是否有硬链接指向它,这些没法靠 size 字段推断。脚本只能帮你看清数据分布,拍板还得人来。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










