用 os.ReadFile 读一个 GBK 编码的日志,直接 string(b) 打印,中文全变成问号,英文正常,文件大小 2.3MB。日志里能对上时间点,这种反而好排。

Go 的 string 只是字节序列,不会做编码转换,GBK 的双字节被当成非法 UTF-8,输出时替换成问号。要转必须先按 GBK 解码成 rune 再编码成 UTF-8。这一点先确认清楚,后面就不用反复试。

go get golang.org/x/text/encoding/simplifiedchinese
go run main.go
file -i access.log

围绕「Go GBK 转 UTF-8」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。

报错里带路径的,先去看那个路径在不在、权限对不对。同一份配置存在多处的,先确认改的是被加载的那一份。

新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。

处理上按这个顺序:引入 golang.org/x/text/encoding/simplifiedchinese;用 GBK.NewDecoder().Bytes 转换后再 string;转换前用 utf8.Valid 判断是否已经是 UTF-8;对非法字节决定报错还是替换 不要静默吞掉。

结果对不对很好判断,转换后打印出正常中文 utf8.Valid 返回 true 行数和原文件一致。

作者 9823189