os.writefile适用于小数据一次性覆盖写入,自动处理文件创建与关闭;流式写入需用os.create或os.openfile配*os.file;高频写入应避免fmt.fprintf,优先file.writestring或bufio.writer批量写入。

os.WriteFile 适合一次性写入小数据
直接把字节切片写进文件,不用管打开、关闭、权限细节,适合配置文件生成、临时文件写入等简单场景。它内部自动处理文件创建、截断和关闭,出错时返回 error,不抛 panic。
注意三点:
-
os.WriteFile总是覆盖原文件(等价于os.O_CREATE | os.O_TRUNC | os.O_WRONLY),不能追加 - 权限参数(如
0644)在 Windows 上被忽略,只影响 Unix-like 系统 - 如果数据量超过几 MB,频繁调用会触发多次系统调用,不如流式写入 +
bufio.Writer
示例:err := os.WriteFile("config.json", []byte(`{"debug":true}`), 0644)
os.Create + WriteString/Write 是流式写入的起点
当你需要多次写入、控制偏移位置,或配合 defer file.Close() 显式管理资源时,就该用 os.Create 或 os.OpenFile 获取 *os.File 句柄。
常见错误现象:cannot use "xxx.txt" (type string) as type io.Writer —— 这是因为直接把路径字符串传给了 fmt.Fprintf 或 file.WriteString,而它们第一个参数必须是实现了 io.Writer 的类型(比如 *os.File)。
关键点:
-
os.Create等价于os.OpenFile(name, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666),会清空已有内容 - 追加写必须显式用
os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644),单独用os.O_APPEND在某些文件系统上可能无效 -
file.WriteString不自动换行,\n得自己加;它比fmt.Fprintf快,因为不走格式化逻辑
fmt.Fprintf 不是万能输出函数,慎用于高频写入
fmt.Fprintf 看起来方便,但它是为调试和低频场景设计的:每次调用都会做类型检查、反射、临时字符串拼接,带来 GC 压力和性能损耗。
高频日志、循环写入字段时,它的开销明显高于 file.WriteString 或 file.Write:
- 写固定前缀 + 时间戳,用
file.WriteString("ts="); file.WriteString(t.Format(...))更快 - 已拼好完整字节切片(比如通过
append构建),直接file.Write(buf)零分配 -
fmt.Fprintf的格式化过程不是并发安全的,多 goroutine 写同一*os.File时需额外加锁
示例对比:fmt.Fprintf(f, "id=%d, name=%s\n", id, name) vs f.WriteString("id="); f.WriteString(strconv.Itoa(id)); f.WriteString(", name="); f.WriteString(name); f.WriteString("\n")
bufio.Writer 是批量写入的性能关键
当你要写入大量小片段(比如逐行日志、CSV 记录),直接调用 file.Write 每次都触发一次系统调用,效率极低。bufio.Writer 把内容先缓存在内存里,等缓冲区满或显式 Flush() 时才真正落盘。
使用时注意:
- 必须在最后调用
w.Flush(),否则最后一段内容可能丢失 - 缓冲区大小默认 4096 字节,写入量大时可设更大(如
bufio.NewWriterSize(f, 64*1024)) -
bufio.Writer本身不是线程安全的,多个 goroutine 共享一个 writer 时要加锁,或者每个 goroutine 自己 new 一个 - 它包装的是
io.Writer,所以可以套在*os.File、网络连接甚至另一个bufio.Writer上
典型结构:w := bufio.NewWriter(file); defer w.Flush(); w.WriteString("..."); w.WriteString("...")
真正容易被忽略的点是:文件句柄泄漏和换行符一致性。没 defer file.Close() 多次运行后会报 too many open files;Windows 下写文本若没手动补 \r\n,某些工具可能显示为单行。这些不是语法错误,但会让程序在线上跑几天后突然崩掉。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











