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

http://msdn.microsoft.com/en-us/library/system.globalization.textelementenumerator.gettextelement.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);
Другие вопросы по тегам