В C # String / Character Encoding в чем разница между GetBytes (), GetString () и Convert ()? - PullRequest
5 голосов
/ 15 сентября 2009

У нас проблемы с получением строки 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.

1 Ответ

10 голосов
/ 15 сентября 2009

После очень беспокойного и смутного утра мы нашли ответ на эту проблему.

Ключевым моментом, который мы упустили, что очень запутало, было то, что строковые типы всегда кодируются в 16-битном (2-байтовом) Unicode . Это означает, что когда мы выполняем GetString () для байтов, они автоматически перекодируются в Unicode за кулисами , и мы не в лучшем положении, чем были в первую очередь.

Когда мы начали получать символьные ошибки и двухбайтовые данные на другом конце, мы знали, что что-то не так, но с первого взгляда на код, который у нас был, мы не могли увидеть ничего плохого. Изучив то, что мы объяснили выше, мы поняли, что нам нужно отправить байтовый массив, если мы хотим сохранить кодировку. К счастью, MicrosoftFunc () имел перегрузку, которая могла принимать массив байтов вместо строки. Это означало, что мы могли преобразовать строку Юникода в кодировку по нашему выбору, а затем отправить ее точно так, как мы ожидаем. Код изменен на:

// 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 () помимо прочего, выполняет Encoding.Convert () из Unicode (поскольку строки всегда являются Unicode) , и указанная кодировка, из которой была вызвана функция, возвращает массив кодированных байтов.
  • GetString () помимо прочего, выполняет Encoding.Convert () из указанной кодировки, из которой была вызвана функция, в Unicode (поскольку строки всегда являются Unicode) и возвращает его как строковый объект.
  • Convert () фактически преобразует байтовый массив одной кодировки в другой байтовый массив другой кодировки. Очевидно, что строки не могут использоваться (потому что строки всегда Unicode) .
...