跳转到主内容
极星编程网:以代码为星,赴技术山海!

Golang初级实战:开发一个简单的磁盘清理工具 Go语言文件权限处理

根本原因是权限不足或路径被占用;Windows下只读文件或Linux/macOS无写权限目录会导致os.RemoveAll失败,且不自动chmod或跳过占用文件。 Go 里
os.RemoveAll
为什么删不掉某些文件? 根本原因不是磁盘满了,而是权限不足或路径被占用。Go 的
os.RemoveAll
在 Windows 上遇到只读文件会直接失败,在 Linux/macOS 上对无写权限的目录也束手无策——它不会自动 chmod,也不会跳过正在使用的文件。 常见错误现象:
remove /tmp/cache/file: permission denied
或
directory not empty
(实际是子项权限问题) 使用场景:清理缓存目录、临时构建产物、用户手动指定的旧日志路径 正确做法:先用
os.Lstat
检查文件属性,对只读文件调用
os.Chmod(path, 0644)
再删;对目录则需递归处理权限 注意:
os.Chmod
对符号链接本身生效,不是目标文件;若要改目标权限,得用
os.Stat
+
os.Chmod
用
filepath.WalkDir
还是
filepath.Walk
?
filepath.WalkDir
是 Go 1.16+ 推荐方式,性能更好、控制更细,尤其适合清理类工具——你能提前终止遍历、跳过子树、避免重复 stat。 关键差异:
WalkDir
传入的是
fs.DirEntry
,不触发额外
Stat
调用;
Walk
每次都调
os.Lstat
,慢且可能因权限失败中断整个遍历 实操建议:用
WalkDir
配合
dirEntry.Type().IsDir()
判断类型,避免再调
os.Stat
容易踩的坑:误把
DirEntry.Name()
当完整路径——它只是 basename,拼路径必须用
filepath.Join
示例逻辑:
filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() && d.Name() == "node_modules" { return filepath.SkipDir } if shouldDelete(path, d) { os.Remove(path) } return nil })
Windows 下删除正在使用的文件总失败? 不是 Go 的锅,是 Windows 文件锁机制导致的。Go 调用系统 API 失败时返回
The process cannot access the file because it is being used by another process
,这时候硬删必然报错。 真实使用场景:清理浏览器缓存(被 chrome 占着)、IDE 临时文件(被 goland 锁住)、日志轮转中的当前文件 可行方案只有两个:跳过(加
continue
),或改用
os.Rename
移走再删(Windows 允许重命名被占用的文件) 别碰
syscall
或第三方库强行解锁——风险高、不可移植、多数情况没必要 判断是否被占用:检查
err
是否为
*os.PathError
且
err.Err == syscall.ERROR_SHARING_VIOLATION
(Windows)或
syscall.EBUSY
(Linux) 清理前要不要校验磁盘空间? 要,但别用
du -sh
外部命令。Go 标准库没直接提供跨平台磁盘用量 API,但
syscall.Statfs
可以——只是它返回的是底层块信息,不是人类友好的 GB/MB。 go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 立即学习 “ go语言免费学习笔记(深入) ”; 推荐做法:用
golang.org/x/sys/unix.Statfs
(Linux/macOS)或
golang.org/x/sys/windows.GetDiskFreeSpaceEx
(Windows),封装成统一函数 为什么不能省:清理工具如果盲目删
/var/log
下所有
.log
,可能刚删完就因磁盘满导致系统服务崩溃 参数注意:
Statfs
的
Bavail
是非 root 用户可用块数,比
Bfree
更贴近真实清理收益 简单估算:可用字节数 =
stat.Bavail * uint64(stat.Bsize)
,再除以
1024*1024*1024
得 GB 事情说清了就结束。权限、路径、平台差异、空间判断——这四点漏掉任一个,工具上线后大概率在某台机器上静默失败。

相关文章