C# · 12月 23, 2021

.net – 为什么C#中的默认编码不推荐?

我用谷歌搜索编码.我发现在C#中不建议使用默认编码.完整的信息是:

Different computers can use different encodings as the default,and
the default encoding can even change on a single computer. Therefore,
data streamed from one computer to another or even retrieved at
different times on the same computer might be translated incorrectly.
In addition,the encoding returned by the Default property uses
best-fit fallback to map unsupported characters to characters
supported by the code page. For these two reasons,using the default
encoding is generally not recommended. To ensure that encoded bytes
are decoded properly,your application should use a Unicode encoding,
such as UTF8Encoding or UnicodeEncoding,with a preamble. Another
option is to use a higher-level protocol to ensure that the same
format is used for encoding and decoding.

来源MSDN

但是如何改变计算机的解码?我不清楚“不同的计算机可以使用不同的编码作为默认值”.

解决方法 上个世纪的许多软件使用单个字节来存储字符.不可知的Unicode的要求.一个字节只能提供256个不同的值,因此这种软件只能处理具有有限数量的不同字符的文本.

几乎每个人都同意字符值0到127表示什么字符,它们是ASCII字符集中的字符. 20世纪60年代早期的一种标准,它将值分配给英文字母中的字母和符号.

这留下了另外128个未分配的值.在其中存在摩擦,它们可以代表不同地方的不同角色,用于表示非英语字形.如希腊语和俄语等语言所必需的,不使用拉丁字母的语言.或越南语和波兰语,具有拉丁字母但使用大量变音符号来标记不同声音的语言.特别是对于具有非常大的字母表的语言,例如中文,韩文和日文,这些都很复杂.这些语言需要双字节编码技巧来将字母表压缩为128个值.

字节值到字符的映射称为代码页.有很多代码页.即使是单一语言.例如,可以在旧的IBM-PC字符集的代码页437中对英语进行编码.具有盒子绘图字符的区别,常用于旧的DOS软件,仍然是控制台模式程序的默认值.代码页1252,这是ANSI代码页,是西欧和美洲Windows程序的默认代码页.和代码页28591,ISO对巴贝尔塔的可爱贡献.我应该提到用于IBM的EBCDIC编码的代码页37,这是一种非ASCII编码,它通过IBM在销售大型计算机方面的实力而幸存下来.否则,历史上的一个值得注意的事故是将一个字节的大小标准化为8位.代码页65001,结束它们的代码页,UTF-8的代码页,一种使用可变长度8位编码的Unicode编码.

这是不好的.没有办法从文本文件中判断哪个代码页用于编码文件中的文本.你必须对它进行有根据的猜测.如果你猜对了,那你只是胡说八道.

Encoding.Default将使用机器的默认ANSI编码,在控制面板的“区域和语言”小程序中配置“非Unicode程序的语言”设置.将其从默认值更改是非常不明智的,这大大增加了旧程序从文本文件中产生无意义的几率.它是西欧和美洲的代码页1252,使用西里尔字母的语言为1251,希腊语为1253,阿拉伯语为1256等.清单is here.

你可以尽可能避免使用Encoding.Default来避免这种痛苦.并且支持UTF-8,这是一种Unicode编码,非常适合.NET支持Unicode.并且是StreamWriter和File等类的默认值.并且能够在文件的开头写入BOM,3个不同的字节,指示用于文本的编码,以便其他程序可以看到您使用的编码.只有在你回到墙上并被迫使用传统软件时才考虑另一种编码.