Используя.NET, как преобразовать ISO 8859-1, закодировал текстовые файлы, которые содержат латинский 1 символ с диакритикой к UTF-8

Я отправляюсь текстовые файлы, сохраненные в формате ISO 88591-1, которые содержат символы с диакритикой от латинского 1 диапазона (а также нормальный ASCII a-z, и т.д.). Как я преобразовываю эти файлы в UTF-8, использующий C# так, чтобы однобайтовые символы с диакритикой в ISO 8859-1 стали допустимыми символами UTF-8?

Я попытался использовать StreamReader с ASCIIEncoding и затем преобразование строки ASCII к UTF-8 путем инстанцирования кодирования ascii и кодирование utf8 и затем использование Encoding.Convert(ascii, utf8, ascii.GetBytes( asciiString) ) — но символы с диакритикой представляются как вопросительные знаки.

Какой шаг я пропускаю?

16
задан Peter Mortensen 20 December 2013 в 15:38
поделиться

2 ответа

Вам необходимо получить правильный объект Encoding . ASCII имеет такое же название: ASCII, что означает, что он поддерживает только 7-битные символы ASCII. Если вы хотите преобразовать файлы, это, вероятно, проще, чем иметь дело с байтовыми массивами напрямую.

using (System.IO.StreamReader reader = new System.IO.StreamReader(fileName,
                                       Encoding.GetEncoding("iso-8859-1")))
{
    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(
                                           outFileName, Encoding.UTF8))
    {
        writer.Write(reader.ReadToEnd());
    }
}

Однако, если вы хотите сами иметь массивы байтов, это достаточно просто сделать с помощью Encoding.Convert .

byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
    Encoding.UTF8, data);

Здесь, однако, важно отметить, что если вы хотите пойти по этому пути, вам следует , а не использовать для ввода-вывода файла программу чтения строк на основе кодирования, такую ​​как StreamReader . FileStream подойдет лучше, так как он будет читать фактические байты файлов.

В интересах полного изучения проблемы может сработать что-то вроде этого:

using (System.IO.FileStream input = new System.IO.FileStream(fileName,
                                    System.IO.FileMode.Open, 
                                    System.IO.FileAccess.Read))
{
    byte[] buffer = new byte[input.Length];

    int readLength = 0;

    while (readLength < buffer.Length) 
        readLength += input.Read(buffer, readLength, buffer.Length - readLength);

    byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
                       Encoding.UTF8, buffer);

    using (System.IO.FileStream output = new System.IO.FileStream(outFileName,
                                         System.IO.FileMode.Create, 
                                         System.IO.FileAccess.Write))
    {
        output.Write(converted, 0, converted.Length);
    }
}

В этом примере переменная buffer заполняется фактическими данными в файле в виде байта [ ] , поэтому преобразование не производится. Encoding.Convert задает кодировку источника и назначения, а затем сохраняет преобразованные байты в переменной с именем ... convert . Затем это напрямую записывается в выходной файл.

Как я уже сказал, первый вариант с использованием StreamReader и StreamWriter будет намного проще, если это все, что вы делаете, но последний пример должен дать вам больше подсказок. относительно того, что на самом деле происходит.

34
ответ дан 30 November 2019 в 15:51
поделиться

Если файлы относительно небольшие (скажем, ~10 мегабайт), вам понадобится всего две строки кода:

  string txt = System.IO.File.ReadAllText(inpPath, Encoding.GetEncoding("iso-8859-1"));
  System.IO.File.WriteAllText(outPath, txt);
13
ответ дан 30 November 2019 в 15:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: