os.Mkdir仅创建最后一级目录,父目录不存在则失败;os.MkdirAll自动逐级创建所有缺失上级目录,类似mkdir -p。

os.Mkdir 和 os.MkdirAll 的区别在哪
创建目录时最常踩的坑,就是用 os.Mkdir 去建多级路径,结果报 no such file or directory。它只建最后一级,父目录不存在就失败;而 os.MkdirAll 会逐级创建缺失的上级目录,更接近 shell 的 mkdir -p 行为。
典型使用场景:保存日志到 ./logs/2024/06/15 这种嵌套路径,直接用 os.MkdirAll 更稳妥。
-
os.Mkdir("a/b/c", 0755)→ 失败(除非a/b已存在) -
os.MkdirAll("a/b/c", 0755)→ 成功(自动建a和a/b) - 权限参数是 Unix 风格 mode,Windows 上仅部分生效(忽略执行位)
删除空目录用 os.Remove,删非空目录得用 os.RemoveAll
os.Remove 只能删空目录或文件;对非空目录会返回 directory not empty 错误。想递归删整个目录树(含子目录、文件),必须用 os.RemoveAll —— 它等价于 shell 的 rm -rf。
注意:这两个函数都**不走回收站,不可逆**,尤其在拼错路径时容易误删。
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
os.Remove("empty_dir")→ 成功(前提是空) -
os.Remove("full_dir")→ 报错:directory not empty -
os.RemoveAll("full_dir")→ 彻底清空,包括所有子项 - 若路径是符号链接,
os.RemoveAll删除的是链接本身,不是目标
检查目录是否存在别用 os.IsNotExist(err),要用双判断
Golang 没有内置的 “exists” 函数,常见错误是只靠 os.Stat + os.IsNotExist 判断,但漏掉了其他可能错误(比如权限不足、路径是文件而非目录)。正确做法是先 os.Stat,再显式检查是否为目录且无错。
示例逻辑:
if fi, err := os.Stat(path); err == nil && fi.IsDir() {
// 目录存在且可访问
} else if os.IsNotExist(err) {
// 目录不存在
} else {
// 其他错误:权限问题、路径是文件、设备忙等
}
-
os.IsNotExist(err)只能确认“不存在”,不能确认“是目录” - 即使
os.Stat成功,也要用fi.IsDir()排除同名文件干扰 - 不要用
os.Open或os.ReadDir来判断存在性——开销大,且失败原因更模糊
跨平台路径拼接必须用 filepath.Join,别手拼 "/" 或 "\"
硬写 "logs/" + date + "/error.log" 在 Windows 上会生成 logs/2024/06/15\error.log 这种混合分隔符路径,导致 os.MkdirAll 创建失败或行为异常。
filepath.Join 会根据运行系统自动选对分隔符(Linux/macOS 用 /,Windows 用 \),还能自动清理冗余分隔符和 ./..。
-
filepath.Join("logs", "2024", "06", "15", "error.log")→ 正确路径 -
filepath.Join("logs/", "2024//06", "..", "06", "error.log")→ 自动规整为logs/2024/06/error.log - 不要用
path.Join(它永远用/,不跨平台)

















