本文介绍 Go 语言中创建目录的标准做法:使用 os.MkdirAll 安全地创建目标路径及其所有父目录,若路径已存在则静默跳过,无需额外判断。
本文介绍 go 语言中创建目录的标准做法:使用 `os.mkdirall` 安全地创建目标路径及其所有父目录,若路径已存在则静默跳过,无需额外判断。
在 Go 中实现“mkdir if not exists”语义,最简洁、可靠且符合惯用法的方式是调用 os.MkdirAll。它不仅会创建指定路径的目录,还会自动递归创建所有缺失的父级目录(如 ./a/b/c 不存在时,会一并创建 a 和 b),更重要的是——当目标路径已存在且为目录时,函数直接返回 nil 错误,不会报错或覆盖。这恰好对应 Node.js 中 fs-extra.ensureDirSync() 的行为。
✅ 正确用法示例
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
// 构建跨平台安全路径(自动处理 / 或 \)
dirPath := filepath.Join(".", "public")
// 创建目录(含所有必要父目录),权限设为 0755(推荐,而非 os.ModePerm)
err := os.MkdirAll(dirPath, 0755)
if err != nil {
fmt.Printf("创建目录失败: %v\n", err)
return
}
fmt.Println("目录已就绪:", dirPath)
}? 说明:
- filepath.Join 保证路径拼接兼容 Windows/Linux/macOS;
- 权限建议使用 0755(即 rwxr-xr-x)而非 os.ModePerm(等价于 0777),避免过度开放权限带来的安全隐患;
- os.MkdirAll 返回 nil 表示成功(无论目录是新建还是原本就存在)。
⚠️ 注意事项
- ❌ 不要手动先调用 os.Stat 判断再 os.Mkdir:存在竞态条件(race condition),可能在判断后、创建前被其他进程删除或修改;
- ❌ 避免使用 os.Mkdir(不带 All):它仅创建最后一级目录,若父目录缺失会失败;
- ✅ 若需区分“新建”与“已存在”,可结合 os.Stat 检查 os.IsNotExist(err),但通常无需此逻辑——MkdirAll 的幂等性已满足绝大多数场景。
✅ 总结
Go 语言原生提供幂等、安全、跨平台的目录创建方案:os.MkdirAll(path, perm) 是唯一推荐方式。它消除了手动检查 + 创建的冗余与风险,是标准库设计的典型范例——简单、健壮、可组合。初学者应优先掌握此模式,并将其作为文件系统初始化操作的默认实践。


















