2010-04-07 3 views
15

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

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

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

+0

Вы пробовали использовать StreamWriter с кодировкой UTF8, чтобы написать AsciiString из к текстовый файл? Это делает это? – Task

+0

@ Task: Его проблема в том, что он никогда не получает строку из 8859-1, а не то, что он не может сохранить ее в UTF-8. –

+0

О, это его проблема, не вопрос. Мне просто легче отлаживать преобразование текста с помощью пары StreamReader/StreamWriter (так что я могу видеть файлы ввода/вывода), а не с вызовом Encoding.Convert. Это может быть только я. – Task

ответ

32

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

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

+0

спасибо за помощь и помощь @Adam за его тщательный ответ – Tim

10

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

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

работал для меня .. –

+0

Для меня тоже. – Cheloide