go源文件必须为utf-8编码;读gbk文件需用simplifiedchinese.gbk.newdecoder()解码字节流,而非强制转换string;写utf-8文件可加bom避免windows记事本乱码。

Go 源文件本身必须是 UTF-8 编码,不支持用 GBK、ISO-8859-1 等其他编码保存 —— 这不是限制,而是语言规范强制要求。所谓“Go 文件编码转换”,实际指的是:读取外部非 UTF-8 文件(如 GBK 文本)、或向外部系统输出非 UTF-8 字节(如写 GBK 文件),而非修改 .go 源码文件的编码。
Go 读取 GBK 文件为什么会乱码
标准库 os.ReadFile 和 bufio.Scanner 不做任何编码解析,只是原样返回字节流;当文件是 GBK 编码时,string(b) 强制解释为 UTF-8,双字节汉字就会被拆成非法序列,显示为 或一堆问号。
- 别用
strings.ToValidUTF8补救 —— 它只替换非法 UTF-8 序列,不会还原原始 GBK 意图,信息已丢失 - 先确认真实编码:Linux/macOS 用
file -i filename;Windows 下看 VS Code 状态栏右下角,不是“UTF-8”就大概率是 GBK - GBK 文件通常不含 BOM,若开头有
0xEF 0xBB 0xBF(UTF-8 BOM),需手动截掉前 3 字节再喂给simplifiedchinese.GBK.NewDecoder()
用 simplifiedchinese.GBK.NewDecoder() 正确读 GBK
核心是「解码字节 → 得到合法 UTF-8 []byte」,不是字符串强制转换。推荐用 transform.NewReader 流式处理,避免一次性加载大文件到内存。
- 导入包:
"golang.org/x/text/encoding/simplifiedchinese"和"golang.org/x/text/transform" - 读文件后立刻套解码器:
reader := transform.NewReader(file, simplifiedchinese.GBK.NewDecoder()) - 用
io.ReadAll或bufio.NewReader读取,结果是合法 UTF-8 字节,可安全转string - 错误处理要区分:
encoding.InvalidUnreadableError表示不可解码字节(如造字),io.EOF是正常结束
写文件时加 UTF-8 BOM 防止 Windows 记事本误读
Go 写出的 UTF-8 文件本身完全正确,但 Windows 记事本默认把无 BOM 的 UTF-8 当作“ANSI”(即当前系统编码,通常是 GBK),一打开就乱码 —— 这锅不在 Go,在记事本。
- 写入前先写 BOM:
f.Write([]byte{0xEF, 0xBB, 0xBF}) - 别用
os.WriteFile—— 它无法插 BOM,改用os.OpenFile+io.WriteString或f.Write - 如果目标明确要 GBK(如对接老系统),用
simplifiedchinese.GBK.NewEncoder()编码后再写,别手动映射字符 - 注意:
encoder.Bytes([]byte(s))可能返回encoding.ErrUnsupported(如 emoji 无 GBK 对应码位),必须检查 err
最易被忽略的是:GBK 解码器对输入字节非常敏感,含多余 BOM、混入控制字符、或部分字节损坏,都会直接报错退出,而不是跳过 —— 所以生产环境建议先用 chardet 类库探测编码,再选对应解码器,别硬刚。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











