UTF-8转GB2312后字符丢失,已转换的字符串能否恢复?
UTF-8转GB2312后字符丢失,已转换的字符串能否恢复?
嘿,这个问题我太熟悉了,经常碰到新手处理编码转换踩这个坑!咱们先聊聊你的场景,再给你明确答案。
首先看你调整后的代码(把Encoding.Default换成了明确的GB2312编码):
byte[] data_utf8 = { 123, 34, 107, 101, 121, 34, 58, 32, 34, 229, 188, 186, 229, 155, 158, 229, 163, 176, 34, 125 }; Console.WriteLine(string.Join(", ", data_utf8)); Console.WriteLine(Encoding.UTF8.GetString(data_utf8)); var gb2312_String = Encoding.GetEncoding("gb2312").GetString(data_utf8); var gb2312_bytes = Encoding.GetEncoding("gb2312").GetBytes(gb2312_String); Console.WriteLine(string.Join(", ", gb2312_bytes)); Console.WriteLine(Encoding.UTF8.GetString(gb2312_bytes));
你看到的输出里最后一个“声”变成了问号,核心原因是:GB2312的字符集范围比UTF-8小太多,你的“声”对应的UTF-8字节序列(229,163,176)不在GB2312的编码映射表里。当用GB2312解码UTF-8字节时,遇到无法识别的序列,编码库会自动用问号(ASCII码63)替代这个“处理不了”的部分——这一步是不可逆的!
那能不能从已经变成{"key": "强回?"}的字符串恢复原内容?
答案是几乎不可能。因为问号是个通用占位符,它只告诉你“这里有个字符我识别不了”,但完全没保留原字节的任何信息。你没法从一个问号反推出它原本是哪个UTF-8字节序列,毕竟有N多个字符的UTF-8序列在GB2312里都无法映射,最后都会变成问号。
给你两个实打实的建议:
- 尽量全程用UTF-8处理文本,不管是读文件、存数据还是网络传输,UTF-8是通用编码,几乎不会出现字符丢失的问题;
- 如果非得在UTF-8和GB2312之间转换,别用默认的替换策略。可以指定
EncoderFallback.ExceptionFallback或者自定义回退策略,这样遇到无法映射的字符时会直接抛出异常,让你第一时间发现问题,而不是等字符丢了才后知后觉。
备注:内容来源于stack exchange,提问作者Eric Qiang
相关产品推荐
相关产品推荐

