最简单的方式是用os.Create创建并覆盖写入文件,但它会清空同名文件;若需“仅在不存在时创建”,应使用os.OpenFile配合O_CREATE|O_EXCL;追加写入则用O_APPEND;一次性写入推荐os.WriteFile。

直接用 os.Create 创建并写入新文件最简单,但要注意它会清空同名文件——如果你本意是“只在不存在时创建”,就得换 os.OpenFile 配合 O_CREATE | O_EXCL。
用 os.Create 创建并覆盖写入
这是最常见也最容易上手的方式,适合配置文件生成、临时输出等场景。它隐式做了三件事:创建文件(若不存在)、截断已有文件(若存在)、以读写权限打开。
-
os.Create("log.txt")等价于os.OpenFile("log.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) - 默认权限是
0666,但受系统umask影响,实际可能是0644或0600;如需精确控制,显式传参更稳妥 - 必须检查
err,且务必用defer file.Close(),否则文件句柄泄漏、内容可能未刷盘 - 写入推荐用
file.WriteString()(字符串)或file.Write([]byte{...})(字节),别混用bufio.Writer后忘了Flush()
用 os.OpenFile 实现“仅新建”或“追加”
当你要避免误删已有文件,或想保留原内容继续追加(比如日志),os.Create 就不够用了,得手动组合 flag。
- “仅新建,存在即报错”:
os.OpenFile("config.json", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)——O_EXCL是关键,配合O_CREATE才生效 - “追加写入”:
os.OpenFile("app.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)—— 不会截断,所有写入自动到末尾 - 权限值建议用八进制字面量(如
0600),不要写成十进制384,易读性差还容易出错 - 如果同时需要读和写(比如先读旧配置再改写),用
os.O_RDWR,但注意O_TRUNC仍会清空,得自己判断逻辑
os.WriteFile:一行覆盖写入,不关心打开细节
Go 1.16+ 推荐的快捷方式,适合“写完就走”的一次性操作,内部自动处理创建、写入、关闭。
立即学习“go语言免费学习笔记(深入)”;
- 签名是
os.WriteFile(name string, data []byte, perm FileMode) error,没有返回文件句柄,没法中途读或追加 - 权限参数直接生效,不受 umask 干扰(因为它是用
openat系统调用 +chmod两步实现的) - 错误只在写失败时返回,不区分“创建失败”还是“写入失败”,调试时不如
os.Create明确 - 示例:
os.WriteFile("data.json", []byte(`{"name":"go"}`), 0644)
权限设置和 flag 组合是高频出错点,尤其是 O_EXCL 必须和 O_CREATE 一起用,单独传无效;还有人把 0644 写成 644 导致权限变成 01204(八进制解析错误)。实际写的时候,建议先明确意图:是覆盖?追加?还是严格新建?再选对应 API,别硬套 os.Create。


















