UTF32 и C# проблемы
Так что у меня проблемы с кодировкой символов. Когда я помещаю следующие два символа в текстовый файл в кодировке UTF32:
鸕
и затем запустите на них этот код:
System.IO.StreamReader streamReader =
new System.IO.StreamReader("input", System.Text.Encoding.UTF32, false);
System.IO.StreamWriter streamWriter =
new System.IO.StreamWriter("output", false, System.Text.Encoding.UTF32);
streamWriter.Write(streamReader.ReadToEnd());
streamWriter.Close();
streamReader.Close();
Я получил:
鸕
鸕
(один и тот же символ дважды, т.е. входной файл!= вывод)
Несколько вещей, которые могут помочь: Hex для первого персонажа:
15 9E 02 00
И для второго:
15 9E 00 00
Я использую Gedit для создания текстового файла, моно для C#, и я использую Ubuntu.
Также не имеет значения, если я указываю кодировку для входного или выходного файла, просто не нравится, если он находится в кодировке UTF32. Работает, если входной файл в кодировке UTF-8.
Входной файл выглядит следующим образом:
FF FE 00 00 15 9E 02 00 0A 00 00 00 15 9E 00 00 0A 00 00 00
Это ошибка или это только у меня так?
Спасибо!
5 ответов
К, так что я понял это, я думаю, это похоже на работу сейчас. Оказывается, поскольку коды для символов были 15 9E 02 00 и 15 9E 00 00, то их нельзя хранить в одном UTF-16. char
, Таким образом, вместо этого UTF16 использует эти суррогатные пары, где есть два разных символа, которые действуют как один "элемент". Чтобы получить элементы, мы можем использовать:
StringInfo.GetTextElementEnumerator(string fred);
и это возвращает строку с суррогатными парами. Относитесь к этому как к одному персонажу.
Посмотреть здесь:
http://msdn.microsoft.com/en-us/library/system.globalization.stringinfo.aspx
Надеюсь, это поможет кому-то:D
Я попробовал это, и это хорошо работает на моем ПК.
System.IO.StreamReader streamReader = new System.IO.StreamReader("input", true);
System.IO.StreamWriter streamWriter = new System.IO.StreamWriter("output", false);
streamWriter.Write(streamReader.ReadToEnd());
streamWriter.Close();
streamReader.Close();
Может быть, текст, который вы думаете, в UTF32 нет.
Из раздела "Примечания" MSDN для конструктора StreamReader:
Этот конструктор инициализирует кодирование в соответствии с параметром encoding и размером внутреннего буфера до 1024 байтов. Объект StreamReader пытается обнаружить кодировку, просматривая первые три байта потока. Он автоматически распознает UTF-8, Unicode с прямым порядком байтов и Unicode с прямым порядком байтов, если файл начинается с соответствующих меток порядка байтов. В противном случае используется предоставляемая пользователем кодировка. См. Метод Encoding.GetPreamble для получения дополнительной информации.
Весьма вероятно, что метки порядка байтов в начале вашего файла на самом деле указывают на UTF 16 (или что-то в этом роде), и поэтому он не использует вашу явно указанную кодировку UTF 32.
При записи вы не указываете UTF-32, поэтому по умолчанию используется Encoding.UTF8.
Из MSDN:
Этот конструктор создает StreamWriter с кодировкой UTF-8 без метки порядка байтов (BOM), поэтому его метод GetPreamble возвращает пустой байтовый массив. Чтобы создать StreamWriter с использованием кодировки UTF-8 и спецификации, рассмотрите возможность использования конструктора, который задает кодировку, например StreamWriter(String, Boolean, Encoding).
Я думаю, что вам нужно указать ту же кодировку (Encoding.UTF32
) также для вашего StreamWriter
,
РЕДАКТИРОВАТЬ:
Обычно это не требуется между кодовыми страницами UTF, но я бы также попробовал это:
Encoding utf8 = Encoding.UTF8;
Encoding utf32 = Enconding.UTF32;
byte[] utf8Bytes = utf8.GetBytes(yourText);
byte[] utf32Bytes = Encoding.Convert(utf8, utf32, utf8Bytes);
string utf32Text = iso.GetString(utf32Text);