Skip to content

GBK 文件不再被改花:Claude Code 拒绝编辑非 UTF-8 文件 ​

国内不少老项目里还躺着 GBK 编码的文件:早年的 Java / C# 工程、Windows 上导出的配置、某些 .bat 和 .ini。让 Claude Code 去改这种文件,过去可能出现一个很糟的结果:它只想改一行,保存后整份文件里的中文都坏了。

CLI 2.1.296 修掉了这个问题:

Edit 和 NotebookEdit 在不是合法 UTF-8 的文件(Windows-1252、Shift-JIS、GBK 等)里,会把每一个非 ASCII 字符都替换掉——这个问题已修复,这类编辑现在会被拒绝。

以前到底会发生什么 ​

按 changelog 的描述,旧版本的 Edit / NotebookEdit 在这类文件上做一次编辑,会把文件里每一个非 ASCII 字符都替换掉。也就是说,Claude 只改了其中一处,写回去时没动过的中文也一起坏了,只剩 ASCII 部分保持原样。

麻烦在于这种损坏不太显眼:

  • 编辑本身「成功」了,Claude 也会汇报改好了;
  • 你在终端里看 diff,可能只觉得「怎么改了这么多行」;
  • 等编译、运行或者别人打开文件,才发现注释、字符串、界面文案全成了乱码。

如果文件没进 git,或者已经和其他改动一起提交,恢复起来就很痛苦。

现在的行为 ​

2.1.296 起,Edit 和 NotebookEdit 发现目标文件不是合法 UTF-8 时,不再硬改,而是拒绝这次编辑。换句话说:

  • 文件保持原样,不会被悄悄写坏;
  • Claude 会得到「编辑被拒」的结果,需要换个办法处理;
  • UTF-8 文件(包括带中文的)不受影响,照常编辑。

这是一个「宁可不改,也不改坏」的修复。对 Windows 用户和维护老代码的团队尤其重要。

老项目怎么办:先转码 ​

遇到被拒的情况,最干净的做法是把文件统一转成 UTF-8,再让 Claude 正常编辑。

确认编码:

bash
file -i src/legacy/Config.java

转成 UTF-8(GBK 举例):

bash
iconv -f GBK -t UTF-8 src/legacy/Config.java > /tmp/Config.java && mv /tmp/Config.java src/legacy/Config.java

批量转换前先提交一次,方便对比和回退。转完后检查一下构建配置:比如 Java 项目的编译编码、IDE 的文件编码设置,避免它们还按 GBK 读。

必须保留原编码时: 有些文件(被旧系统按 GBK 读取的配置、外部约定的数据文件)不能改编码。这时可以在 CLAUDE.md 里写明哪些目录是 GBK,并让 Claude 用 Bash 调 iconv 先转出 UTF-8 副本、改完再转回,而不是直接用 Edit 动原文件。转回之后记得自己 diff 确认。

同一条线上的几次编码修复 ​

Claude Code 这一年陆续修过不少编码相关的问题,可以对照看:

版本修复
2.1.94stream-json 输入输出在分块边界切开 UTF-8 序列时,中文等多字节文字被写成 U+FFFD
2.1.214Windows 上 PowerShell 工具里的 Python 脚本读非 UTF-8 标准输入时报 UnicodeDecodeError;PowerShell 5.1 下 >、>> 写出 UTF-16LE 文件
2.1.239以 UTF-8 BOM 开头的 agents、skills、commands .md 文件被静默忽略
2.1.296Edit / NotebookEdit 改坏非 UTF-8 文件,改为拒绝编辑

Windows 环境的更多配置建议,可以看 Windows 环境配置。

小结 ​

  • 2.1.296 起,Edit / NotebookEdit 遇到 GBK、Shift-JIS、Windows-1252 等非 UTF-8 文件会拒绝编辑,不再把非 ASCII 字符全部替换掉。
  • 被拒时优先把文件转成 UTF-8;必须保留原编码的,用 iconv 转副本的方式处理,并在 CLAUDE.md 里写清楚。
  • 用旧版本改过 GBK 文件的,建议回头用 git diff 检查一下有没有被改花的中文。

升级后用 claude --version 确认 ≥ 2.1.296。

Claude-cn.org,专注于 Claude Code 中文教程