最简单的一次性写入用os.WriteFile;需追加或分块写入时用os.OpenFile配合标志位;频繁小写入推荐bufio.Writer提升性能;务必检查错误、确认路径和权限。

用 ioutil.WriteFile 一次性写入字符串最简单
如果只是把一段文本(比如 JSON、配置内容)完整覆盖写入文件,ioutil.WriteFile 是最直接的选择。它内部自动处理打开、写入、关闭和权限设置,一行代码搞定。
注意:Go 1.16+ 中 ioutil 已被移到 os 包,应改用 os.WriteFile —— 否则会报 undefined: ioutil 错误。
示例:
err := os.WriteFile("config.json", []byte(`{"port":8080}`), 0644)
if err != nil {
log.Fatal(err)
}
-
0644是 Unix 权限,Windows 下会被忽略 - 写入前会清空原文件,不支持追加
- 不适合大文件,因为整个内容需先转成
[]byte加载进内存
用 os.OpenFile + *os.File.Write 控制写入模式
需要追加内容、避免覆盖、或分块写入时,得手动管理文件句柄。核心是用 os.OpenFile 指定标志位,再调用 Write 或 WriteString。
立即学习“go语言免费学习笔记(深入)”;
常见标志组合:
-
os.O_CREATE | os.O_WRONLY | os.O_TRUNC→ 覆盖写入(默认行为) -
os.O_CREATE | os.O_WRONLY | os.O_APPEND→ 追加写入(日志场景常用) -
os.O_CREATE | os.O_WRONLY | os.O_EXCL→ 仅当文件不存在时创建(防覆盖)
示例(追加):
f, err := os.OpenFile("log.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close()
_, err = f.WriteString("request completed\n")
if err != nil {
log.Fatal(err)
}
用 bufio.Writer 提升小量多次写入性能
如果循环中频繁调用 WriteString(比如逐行写日志),每次系统调用开销大。bufio.Writer 提供缓冲,攒够一定量或显式 Flush 时才真正落盘。
注意:忘记 Flush 会导致最后一部分数据丢失。
f, _ := os.OpenFile("data.txt", os.O_CREATE|os.O_WRONLY, 0644)
defer f.Close()
w := bufio.NewWriter(f)
defer w.Flush() // 关键:必须 defer 或显式调用
for _, s := range []string{"a", "b", "c"} {
w.WriteString(s + "\n")
}
- 默认缓冲区大小是 4096 字节,可通过
bufio.NewWriterSize自定义 -
w.Flush()返回的error应检查,尤其在关键写入后 - 不要对同一个
*os.File混用Write和bufio.Writer,缓冲逻辑会冲突
写入错误常被忽略的三个关键点
实际项目里,很多“文件没写进去”的问题不是逻辑错,而是错误处理疏漏:
-
os.WriteFile和*os.File.Write都返回error,但常被写成_ := ...直接丢弃 - 文件路径含相对路径时,工作目录不一定是项目根目录,建议用
os.Getwd()打印确认 - Windows 下路径分隔符用
\,但硬编码"dir\file.txt"在某些 shell 或 IDE 里会因转义失效,统一用filepath.Join("dir", "file.txt")
权限不足、磁盘满、路径不存在等错误,只有检查 err 才能暴露出来。别让 nil 的假象掩盖真实问题。










