StreamReader и кодировка

Рейтинг: 4Ответов: 1Опубликовано: 18.04.2015

Допустим, у меня есть файл и у него может быть любая кодировка. Как с помощью StreamReader корректно прочитать данные из этого файла, чтобы потом записать их в другой файл с кодировкой UTF-8?

Ответы

▲ 7Принят

Никак. Гарантировано рабочего решения не существует. Для того, чтобы работать с текстовым файлом, система обязана знать его кодировку.

Что вы можете попробовать:

  1. Используйте StreamReader без указания кодировки. Он попробует продетектировать, и в нормальных случаях (а это означает обычно Unicode-кодировки) ему это удаётся.
  2. Попробуйте сдетектировать кодировку на основе частотного анализа. Если вам известен язык, на котором написан ваш текст, вы можете определить относительную частоту символов в текстах (это будет ожидаемое распределение частот), попробовать пооткрывать текст в кодировках, релевантных для этого языка (например, для русского языка это CP1251, CP866, KOI8-R и т. п.), и посмотреть, в какой из них распределение частот символов будет ближе всего к той самой относительной частоте. (Это реализовано, например, в редакторе Far Manager'а).

В ответах на этот вопрос есть несколько примеров с кодом, комбинирующих эти подходы.

В любом случае, на будущее: текст не имеет права храниться без кодировки. Текст без кодировки — никому не нужные данные. Всегда знайте кодировку, в которой лежит ваш текст.


Если же вы знаете кодировку файла, то всё гораздо проще:

var srcEncoding = Encoding.GetEncoding(1251);
var dstEncoding = Encoding.UTF8;

using (var src = new StreamReader(srcFileName, encoding: srcEncoding))
using (var dst = new StreamWriter(dstFileName, append: false, encoding: dstEncoding))
{
    string line;
    while ((line = src.ReadLine()) != null)
        dst.WriteLine(line);
}