Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#字符串/字符编码中,GetBytes()、GetString()和Convert()之间有什么区别?_C#_String_Unicode_Encoding_Utf 8 - Fatal编程技术网

在C#字符串/字符编码中,GetBytes()、GetString()和Convert()之间有什么区别?

在C#字符串/字符编码中,GetBytes()、GetString()和Convert()之间有什么区别?,c#,string,unicode,encoding,utf-8,C#,String,Unicode,Encoding,Utf 8,我们在将Unicode字符串转换为UTF-8字符串以通过线路发送时遇到问题: // Start with our unicode string. string unicode = "Convert: \u10A0"; // Get an array of bytes representing the unicode string, two for each character. byte[] source = Encoding.Unicode.GetBytes(unicode); // Co

我们在将Unicode字符串转换为UTF-8字符串以通过线路发送时遇到问题:

// Start with our unicode string.
string unicode = "Convert: \u10A0";

// Get an array of bytes representing the unicode string, two for each character.
byte[] source = Encoding.Unicode.GetBytes(unicode);

// Convert the Unicode bytes to UTF-8 representation.
byte[] converted = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, source);

// Now that we have converted the bytes, save them to a new string.
string utf8 = Encoding.UTF8.GetString(converted);

// Send the converted string using a Microsoft function.
MicrosoftFunc(utf8);

虽然我们已经将字符串转换为UTF-8,但它并不是以UTF-8的形式到达的。

经过一个非常麻烦和混乱的上午,我们找到了这个问题的答案

我们缺少的一个关键点是字符串类型总是用16位(2字节)Unicode编码,这让我们非常困惑。这意味着,当我们对字节执行GetString()时,它们会在幕后自动重新编码为Unicode,我们的境况并不比当初好多少

当我们开始得到字符错误和另一端的双字节数据时,我们知道有些地方出了问题,但只要看一眼我们的代码,我们就看不出任何错误。在了解了上面的解释之后,我们意识到如果我们想保留编码,就需要发送字节数组。幸运的是,MicrosoftFunc()有一个重载,可以采用字节数组而不是字符串。这意味着我们可以将unicode字符串转换为我们选择的编码,然后完全按照我们的预期发送它。代码更改为:

// Convert from a Unicode string to an array of bytes (encoded as UTF8).
byte[] source = Encoding.UTF8.GetBytes(unicode); 

// Send the encoded byte array directly! Do not send as a Unicode string.
MicrosoftFunc(source);
总结: 因此,综上所述,我们可以看到:

  • GetBytes()除其他外,从Unicode(因为字符串总是Unicode)和调用函数的指定编码执行编码.Convert(),并返回编码字节数组
  • GetString()除其他外,执行从调用函数的指定编码到Unicode(因为字符串始终是Unicode)的编码.Convert(),并将其作为字符串对象返回
  • Convert()实际上是将一种编码的字节数组转换为另一种编码的字节数组。显然不能使用字符串(因为字符串总是Unicode)

这里有些混乱。没有称为Unicode的编码。Unicode是字符集的名称,可以使用编码(例如UTF-8或UTF-16)以字节为单位进行编码。因此,
Encoding.Unicode
被严重命名错误,因为它实现了小端UTF-16编码。它真的应该被称为
Encoding.UTF16LE
。字符串是字符序列,它们在底层平台中存储的编码是不相关的。这是一个实现细节,它们碰巧存储为UTF-16。调用它
编码没有什么错。Unicode
,在某种程度上Unicode是一种编码。平台选择使用UTF-16或UTF-8只是一个实现细节。当您使用字符串时,它的内部编码实际上并不重要。只要平台提供了在输出中编码的方法,您甚至不必知道内部编码是什么。有些语言,比如python,在API中根本不说任何编码,他们只是称之为“字符串”,然后对其进行编码和解码,这是一种更干净的方法。