Толик Панков
hex_laden
............ .................. ................

October 2030
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

Толик Панков [userpic]
Подводный камень при чтении файла с помощью File.ReadAllText

Иногда проще прочитать файл, как текстовый в однобайтовой кодировке, чтобы что-нибудь там поделать с помощью стандартных string.Replace/string.Remove и т.д., иногда даже если файл не совсем текстовый, потому что таких же удобных функций для работы с массивом байт нет (или я не нашел).
Это, наверняка, адский быдлокод, но все-таки вполне альтернатива изобретению совсем уж дикого велосипеда.

А у меня речь шла о текстовых файлах, правда, неизвестно в какой кодировке, и символах, которые нужно искать/менять. Символы от кодировки не зависели, посему любой файл можно было рассматривать, как текстовый, в любой однобайтовой кодировке. Главное, в какой кодировке открыл, в той же потом и сохранить.
Так вот File.ReadAllText пытается автоматически определить кодировку файла на основе наличия меток порядка следования байтов и принудительная установка кодировки не помогает. Если в файле встретился зловредный BOM, то ReadAllText наплюет на твои указания кодировки с высокой колокольни и откроет в той, на которую ему BOM указывает, а при сохранении, соответственно, будет глюк и текст превратится в тыкву.

Беда, конечно, решается стандартно, чтением файла с помощью StreamReader и записью с помощью StreamWriter, которые себе такой самодеятельности не позволяют, но "осадочек остался".

Пример
Скачать

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2018/02/18/podvodnyj-kamen-pri-chtenii-fajla-s-pomoshhyu-file-readalltext/

Tags: ,
Comments

А ведь я ещё сто лет на зад написал такую утиль. Но нет, надо обязательно свой костыль изобрести...

Привет! Спасибо, но оно на C, если только DLL из нее сделать...

Слушай, подскажи лучше какой-нибудь оптимальный способ определить, что в текстовом файле UTF-16 BE/LE, BOM может не быть. Я довольно по-дурацки определяю по наличию символов перевода строк. В UTF-8 или однобайтных кодировках они просто \r\n (\r \n), а в UTF-16 там либо перед символом 0x0, либо после. В принципе оно работает, но слишком легко такое налюбить, тем более нужен многострочный файл. Про мозилловскую библиотеку знаю, но неохота ради такой мелочи ее с собой таскать.

По пробелу проще. Если он у тебя кодируется 0x20 0x00, то это UTF-16LE, если 0x00 0x20, то UTF16BE

Точно! Спасибо!

*хлопнув себя копытом по лбу, сокрушаюсь, как я мог забыть про пробел*