上个世纪的许多软件都使用单个字节来存储字符。不知道 Unicode 的要求。一个字节只能提供 256 个不同的值,因此此类软件只能处理具有有限数量的不同字符的文本。
几乎每个人都同意字节值 0 到 127 代表什么字符,它们是 ASCII 字符集中的字符。1960 年代初期的一种标准,为英文字母表中的字母和符号赋值。
这留下了另外 128 个未分配的值。难点在于,它们可以在不同的地方表示不同的字符,用来表示非英文字形。例如在希腊语和俄语等不使用拉丁字母的语言中是必需的。或者越南语和波兰语,这些语言有拉丁字母,但使用大量变音符号来标记不同的声音。尤其是对于具有非常大字母的语言,如中文、韩文和日文,尤其令人费解。此类语言需要双字节编码技巧来将字母表压缩为 128 个值。
字节值到字符的映射称为代码页。有许多代码页。即使是单一语言。例如,可以在代码页 437(旧的 IBM-PC 字符集)中对英语进行编码。具有绘图字符的独特之处,通常用于旧的 DOS 软件,并且仍然是控制台模式程序的默认设置。还有代码页 1252,这是一个 ANSI 代码页,它是西欧和美洲的 Windows 程序的默认设置。以及代码页 28591,ISO 对巴别塔的可爱贡献。我应该提到代码页 37,用于 IBM 的 EBCDIC 编码,这是一种非 ASCII 编码,它在 IBM 销售大型计算机方面的实力得以幸存。否则,历史上一个值得注意的事故将一个字节的大小标准化为 8 位。还有代码页 65001,结束它们的代码页,UTF-8 的代码页,
这是不好的。无法从文本文件中分辨出哪个代码页用于对文件中的文本进行编码。你必须对此做出有根据的猜测。如果你猜错了,那你只会胡说八道。
Encoding.Default 将使用机器的默认 ANSI 编码,在控制面板的区域和语言小程序中配置,“非 Unicode 程序的语言”设置。从默认值更改它是非常不明智的,这大大增加了旧程序从文本文件中产生废话的可能性。西欧和美洲的代码页为 1252,使用西里尔字母的语言为 1251,希腊语为 1253,阿拉伯语为 1256,等等。清单在这里。
您可以通过尽可能避免 Encoding.Default 来避免这种痛苦。并支持 UTF-8,这是一种 Unicode 编码,与 .NET 对 Unicode 的支持非常配合。并且是 StreamWriter 和 File 等类的默认设置。并且能够在文件的开头编写一个 BOM,3 个不同的字节指示用于文本的编码,以便其他程序可以看到您使用的编码。仅当您背井离乡并被迫使用旧版软件时才考虑另一种编码。