小文件读写直接用os.readfile和os.writefile,适合配置文件、临时token、小日志快照等单次操作;大文件或需逐行处理时必须用os.open+bufio.scanner;ioutil已弃用,升级后编译失败。

小文件直接用 os.ReadFile 和 os.WriteFile,大文件或需逐行处理时必须换 os.Open + bufio.Scanner;ioutil 已彻底弃用,升级后编译会失败。
os.ReadFile 和 os.WriteFile 适合哪些场景
这两个函数是 Go 1.16+ 的默认推荐入口,封装了打开、读/写、关闭全过程,不用手动管理 File 句柄。适用于配置文件(JSON/YAML)、临时 token、小日志快照等单次操作。
-
os.ReadFile返回[]byte,不是string—— 要打印或解析文本得显式转:string(data),但不校验 UTF-8 合法性 -
os.WriteFile第三个参数是权限perm,Linux/macOS 下必须设对(如0644),设成0会导致文件不可读;Windows 上基本忽略该参数 - 它总是覆盖写入 —— 想追加内容?不能用这个,得切到
os.OpenFile配合os.O_APPEND - 路径不存在时不会自动创建父目录,报错
open /tmp/a/b/c.json: no such file or directory,得提前用os.MkdirAll
大文件为什么不能用 os.ReadFile
几十 MB 以上就容易触发 runtime: out of memory。它把整个文件一次性加载进内存,没做流控,也不支持中断或按需读取。
-
bufio.Scanner默认单行上限 64KB,超长行会返回scanner.ErrTooLong;可调用scanner.Buffer扩容,但别无脑设成几 MB - 逐行处理时,
scanner.Text()返回新字符串(拷贝),scanner.Bytes()返回底层切片(引用),后者更省内存但生命周期受限于下一次Scan() - 别在循环里反复调用
os.ReadFile处理多文件 —— 每次都全量加载,I/O 和内存开销双爆炸
如何正确追加内容或控制打开模式
追加、清空、只读、读写混用等行为,必须靠 os.OpenFile 组合 flag 实现,os.WriteFile 不提供这些能力。
- 追加写:用
os.O_APPEND | os.O_CREATE | os.O_WRONLY,文件不存在则创建,存在则跳到末尾写 - 覆盖写(清空后写):加
os.O_TRUNC,和os.O_CREATE一起用时,存在就清空,不存在就新建 - 读写并存:用
os.O_RDWR,但注意多数场景下“先读后写”要自己控制偏移,不如分开操作清晰 - 权限
perm在os.OpenFile中仅对新建文件生效;已存在文件的权限不会被修改
bufio.Scanner 和 io.Copy 怎么选
两者定位不同:Scanner 是面向“行”的抽象,适合日志过滤、配置解析;io.Copy 是面向“字节流”的搬运工,适合复制大文件、代理响应体等整块传输场景。
-
io.Copy内部用 32KB 缓冲区,性能稳定,无需额外配置;如需更大缓冲,改用io.CopyBuffer并传自定义[]byte -
Scanner的Split方法能换分隔逻辑(比如按 JSON 对象分割),但别用正则自定义分割器 —— 性能差且易出错 - 如果只是把一个文件原样复制到另一个路径,
io.Copy比Scanner+WriteString快得多,也更省内存
真正容易被忽略的是:权限错误常发生在非用户目录(如 /var/log),而路径错误往往卡在父目录未创建;还有就是误以为 os.WriteFile 支持追加 —— 它不支持,永远覆盖。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











