go中utf-8↔gbk转换应使用golang.org/x/text/encoding/simplifiedchinese.gb18030(非deprecated的gbk),配合transform实现流式转换,避免oom;不可用strings.tovalidutf8或强制类型转换,因其不执行编码转换。

Go 里没有内置的编码转换支持
标准库 encoding/xml、encoding/json 等只处理 UTF-8,io 和 os 也完全不感知字符编码。想把 UTF-8 文件转成 GBK,必须引入第三方库——最常用且可靠的是 golang.org/x/text/encoding + golang.org/x/text/transform。
用 golang.org/x/text/encoding 做流式转换
别读完整个文件再转,容易 OOM,尤其处理大文本时。正确做法是边读边转,用 transform.Reader 包裹 *os.File:
import (
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
"os"
)
src, _ := os.Open("in.txt") // 假设是 UTF-8
dst, _ := os.Create("out.txt")
// UTF-8 → GBK:用 GB18030 编码器(兼容 GBK,且 Go 官方只提供 GB18030)
encoder := simplifiedchinese.GB18030.NewEncoder()
writer := transform.NewWriter(dst, encoder)
_, _ = io.Copy(writer, src) // 自动完成转换写入
-
simplifiedchinese.GBK在较新版本中已被标记为 deprecated,实际应优先用simplifiedchinese.GB18030 - GB18030 能无损表示所有 GBK 字符,且支持更多汉字(如生僻字、少数民族文字),兼容性更好
- 如果源文件不是 UTF-8,而是其他编码(如 ISO-8859-1),需先用对应解码器 wrap
src,否则会乱码
转换失败时默认 panic?得手动处理错误
transform.Writer 遇到无法映射的字符(比如 UTF-8 中某个 emoji 在 GBK 里不存在),默认行为是返回 transform.ErrInvalidUTF8 或 transform.ErrEndOfSpan,但 io.Copy 会直接丢弃错误并停止——你可能根本不知道转换失败了。
- 务必检查
io.Copy的返回错误,而不是只看err == nil - 若需容错(例如把无法转换的字符替换成
?),要用transform.Chain+ 自定义transform.SpanningTransformer,或改用transform.String对小段文本做带 fallback 的转换 - 常见错误信息如:
transform: invalid source byte,通常意味着输入不是合法 UTF-8
Windows 上写 GBK 文件要注意 BOM
Windows 记事本识别 GBK 文件依赖 BOM(虽然 GBK 规范本身不要求)。如果你希望生成的 .txt 被记事本正确打开,得手动在文件开头写入 GBK 的 BOM:\x81\x40(注意:这不是 UTF-8 的 \xEF\xBB\xBF)。
- Go 的
simplifiedchinese.GB18030编码器默认不写 BOM - 可以先用
dst.Write([]byte{0x81, 0x40}),再把transform.Writer接在后面写内容 - 但加 BOM 后,该文件对 Linux 工具(如
grep、sed)可能显示异常——是否加,取决于目标使用场景
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











