2

在将编码转换为 UTF-8 时,我在 Windows 平台之间遇到了一些奇怪的行为。如果我有一个带有“扩展 ASCII”字符的字符串,比如商标符号的字符 0x99,我可以在 Windows 7 上使用以下代码对其进行转换:

using System.Text;
...
string DefaultEncodedStr = <<Some string with Extended ASCII chars like 0x99 for TM>>
byte[] DefaultEncodedBytes = Encoding.Default.GetBytes(DefaultEncodedStr);
byte[] UTF8EncodedBytes = Encoding.Convert(Encoding.Default, Encoding.UTF8, DefaultEncodedBytes);
char[] UTF8Chars = new char[Encoding.UTF8.GetCharCount(UTF8EncodedBytes, 0, UTF8EncodedBytes.Length)];
UTF8.GetChars(UTF8EncodedBytes, 0, UTF8EncodedBytes.Length, UTF8Chars, 0);
string UTF8Str = new string(UTF8Chars); 

但是,此代码无法在 Windows Server 2008 R2 上转换初始字符串——“扩展 ASCII”字符仍存在于最终字符串中。

但是,此代码确实适用于 Windows Server 2008 R2:

using System.Text;
...
string DefaultEncodedStr = <<Some string with Extended ASCII chars like 0x99 for TM>>
byte[] DefaultEncodedBytes = Encoding.Default.GetBytes(DefaultEncodedStr)
string UTF8Str = Encoding.UTF8.GetString(DefaultEncodedBytes); 

但是,此代码无法在 Windows 7 上转换字符串!!

是什么赋予了?为什么我看到使用相同内核基础 (Win7) 的桌面类和服务器类操作系统之间的行为不同?我真的需要包含某种平台检测代码来确定如何正确处理编码转换吗?

4

1 回答 1

6

.NET 字符串是 Unicode 字符序列。如果你有一个字符串

string s = "™";

那么字符串由 Unicode U+2122 TRADE MARK SIGN 字符组成。

所以,等效地你可以写

string s = "\u2122";

您可以使用编码将此字符序列转换为字节序列。

一种编码是 UTF-8:

byte[] bytes = Encoding.UTF8.GetBytes(s);
// bytes == { 0xE2, 0x84, 0xA2 }

另一种编码是 Windows-1252:

byte[] bytes = Encoding.GetEncoding("Windows-1252").GetBytes(s);
// bytes == { 0x99 }

因此,如果您有一个表示 Windows-1252 中的字符串并由字节 0x99 组成的字节序列,则可以将其解码为字符串,如下所示:

string result = Encoding.GetEncoding("Windows-1252").GetString(bytes);
// result == "™"

Encoding.Default返回操作系统的默认编码。这可能是 Windows-1252,但不是必须的。始终指定要显式使用的编码。

不同的计算机可以使用不同的编码作为默认编码,甚至可以在单台计算机上更改默认编码。因此,从一台计算机流式传输到另一台计算机或什至在同一台计算机上的不同时间检索的数据可能会被错误地翻译。

也可以看看:

于 2013-03-27T22:33:03.970 回答