Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

StreamReader и кодировка

#c_sharp #кодировка


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


Ответы

Ответ 1



Никак. Гарантировано рабочего решения не существует. Для того, чтобы работать с текстовым файлом, система обязана знать его кодировку. Что вы можете попробовать: Используйте StreamReader без указания кодировки. Он попробует продетектировать, и в нормальных случаях (а это означает обычно Unicode-кодировки) ему это удаётся. Попробуйте сдетектировать кодировку на основе частотного анализа. Если вам известен язык, на котором написан ваш текст, вы можете определить относительную частоту символов в текстах (это будет ожидаемое распределение частот), попробовать пооткрывать текст в кодировках, релевантных для этого языка (например, для русского языка это 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); }

Ответ 2



Если в начале файла не проставлены теги кодировок, то однозначно определить кодировку нельзя, т.е. вам понадобиться указать кодировку в аргументе encoding. var encoding = Encoding.GetEncoding(1251); using (var src = new StreamReader(filePath, encoding: encoding)) { } Или же вы можете воспользоваться алгоритмами, которые определяют кодировку по содержанию файла. Но надо учитывать, что они не дают 100% результата. Одним из эффективных алгоритмов является Mozilla Universal Charset Detector. Одну из его реализаций на c# вы можете найти на github.

Комментариев нет:

Отправить комментарий