Подтвердить что ты не робот

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

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

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

Какой шаг мне не хватает?

4b9b3361

Ответ 1

Вам нужно получить правильный 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 для вашего файла IO. 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 заполняется фактическими данными в файле как byte[], поэтому преобразование не выполняется. Encoding.Convert указывает исходную и целевую кодировку, а затем сохраняет преобразованные байты в переменной с именем... converted. Затем он записывается непосредственно в выходной файл.

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

Ответ 2

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

  string txt = System.IO.File.ReadAllText(inpPath, Encoding.GetEncoding("iso-8859-1"));
  System.IO.File.WriteAllText(outPath, txt);