go读gbk文件必须用simplifiedchinese.gbk.newdecoder().bytes()解码字节流为utf-8,而非string()强制转换;大文件需transform.newreader流式处理,写utf-8文件应加bom避免windows记事本乱码。

Go 本身不支持自动识别或批量转换文件编码,必须显式指定源编码和目标编码,用 simplifiedchinese.GBK 等解码器逐文件处理——这不是限制,而是设计选择:避免隐式转换带来的数据损坏风险。
怎么读取 GBK 文件并转成 UTF-8 字符串
别用 os.ReadFile 后直接 string(),那只是把 GBK 字节当 UTF-8 解释,必然乱码。正确路径是先读字节,再走解码器。
-
os.ReadFile("a.txt")得到的是原始 GBK[]byte,不是字符串 - 用
simplifiedchinese.GBK.NewDecoder().Bytes(data)解码,返回合法 UTF-8[]byte,此时string()才安全 - 若文件开头有 BOM(如
0xBF 0xBE),GBK.NewDecoder()会自动跳过;但手动用bytes.TrimPrefix截 BOM 可能切坏首字符 - 遇到无法映射的造字,默认替换成
;要自定义行为,得用unicode.ReplaceOnError构建 decoder
大文件批量转换时内存爆掉怎么办
一次性 ReadFile + Bytes() 会同时持有原始字节和 UTF-8 字节两份数据,几百 MB 文件很容易 OOM。流式处理才是正解。
- 用
os.Open打开文件,套transform.NewReader(f, decoder),再io.Copy到目标文件或 buffer - 别用
ioutil.ReadAll或bytes.Buffer缓存全文——哪怕只是临时变量,GC 也可能来不及回收 - 每个文件处理完立刻
defer f.Close(),不要等整个批量循环结束 - 并发数控制在 4~6,过高反而因 I/O 竞争和 goroutine 切换拖慢整体速度
写入 UTF-8 文件时为啥 Windows 记事本打开还是乱码
不是 Go 写错了,是记事本默认把无 BOM 的 UTF-8 当作系统本地编码(如 GBK)。加 BOM 就能解决,但要注意位置和时机。
- UTF-8 BOM 是固定三字节:
[]byte{0xEF, 0xBB, 0xBF},必须写在文件最开头 - 别用
os.WriteFile—— 它没法插 BOM;改用os.OpenFile+ 先f.Write(bom)+ 再io.WriteString(f, content) - 如果目标是 GBK 文件(比如对接老系统),BOM 不适用,得用
simplifiedchinese.GBK.NewEncoder()编码后写,而不是直接写[]byte(s) - 写入前检查目标程序是否真需要 BOM:VS Code、Sublime、现代浏览器都不依赖它;只有旧版记事本、Excel、部分国产软件才认
真正容易被忽略的是错误处理——decoder.Bytes() 和 encoder.Bytes() 都可能返回 encoding.InvalidUnreadableError 或 encoding.ErrUnsupported,但很多人只 check err != nil,没区分具体类型,导致部分文件静默失败。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











