Строки в кодировке ASCII и UTF8 имеют разную длину!

Я читаю поток и мне интересно, почему строка в кодировке UTF-8 короче, чем в ASCII.

  ASCIIEncoding encoder = new ASCIIEncoding();
  UTF8Encoding enc = new UTF8Encoding();   
  string response = encoder.GetString(message, 0, bytesRead); //4096
  string responseUtf8 = enc.GetString(message, 0, bytesRead);  //3955

person Hedge    schedule 08.10.2010    source источник


Ответы (4)


Это потому, что поток на самом деле закодирован в UTF-8. Если бы это была кодировка ASCII, строки были бы идентичными.

При чтении в формате ASCII комбинации байтов, представляющие символы вне кодового набора 0–127, будут считываться как отдельные символы и выглядеть как мусор.

При чтении в формате UTF-8 комбинации байтов будут декодированы в правильные символы, каждая многобайтовая комбинация станет одним символом.

(Примечание. Строки не кодируются, кодируется поток. Вы декодируете поток из ASCII или UTF-8 в строку символов Unicode.)

person Guffa    schedule 08.10.2010

UTF-8 обрабатывает строки, отличные от ASCII: в UTF-8 каждый символ может иметь длину 1, 2 или 3 байта. Однако ASCII рассматривает каждый байт как символ. Кодировщик C# UTF-8 считает правильно сформированные символы UTF-8, а не байты. Я надеюсь, это поможет вам.

person Adonais    schedule 08.10.2010
comment
Я думаю, это правильно. Обратите внимание, что у ASCIIEncoding нет обнаружения ошибок, а у UTF8Encoding есть. - person Matthew Flaschen; 09.10.2010
comment
Как указано в документации, ASCIIEncoding не имеют обнаружения ошибок. Таким образом, он с радостью декодирует байты, которые не имеют смысла как ASCII, в вопросительные знаки. - person Matthew Flaschen; 09.10.2010
comment
@Matthew: Чем это отличается от UTF8Encoding? Он будет счастлив «декодировать» последовательности байтов, которые не имеют смысла, поскольку UTF-8 в U+FFFD... - person Timwi; 09.10.2010
comment
@Timwi, как я уже говорил, UTF8Encoding имеет обнаружение ошибок, что означает вы можете указать ему генерировать исключение. - person Matthew Flaschen; 09.10.2010
comment
@Matthew: я вижу, вы говорите о логическом параметре конструктора. Это действительно не было ясно из «у него есть обнаружение ошибок». Кроме того, я не понимаю, как это относится к этому ответу... - person Timwi; 09.10.2010
comment
@Timwi, да, термин «обнаружение ошибок» используется в документации, а не я придумал. Если бы у ASCIIEncoding было обнаружение ошибок, вы могли бы вызвать его в таких ситуациях, как вопрос, когда ему передаются недопустимые байты. Так что я определенно нахожу разницу между двумя классами актуальной. - person Matthew Flaschen; 09.10.2010

Поскольку при декодировании байтов ASCIIEncoding заменяет все байты больше 127 (0x7F) знаком вопроса (?), который является одним символом, в то время как UTF8Encoding правильно декодирует многобайтовые последовательности UTF-8 в одиночные символы (например, три байта 232,170,158 становятся единственный символ 語).

person Timwi    schedule 08.10.2010

Возможно, сообщение содержало некоторые символы, которые невозможно было закодировать как один байт в UTF-8<. /а>.

person Martin Törnwall    schedule 08.10.2010