Я нашел этот вопрос, работая над обработкой большой коллекции древних текстовых файлов в хорошо отформатированных PDF-файлах.Ни один из файлов не имеет спецификации, а самые старые из них содержат кодовые точки кодовой страницы 1252, которые вызывают неправильное декодирование в UTF8.Это происходит только в некоторых случаях, UTF8 работает большую часть времени.Кроме того, последние текстовые данные содержат кодовые точки UTF8, поэтому это смешанный пакет.
Итак, я также поставил ", чтобы определить, какая кодировка входного файла имеет" и послечтение Как определить кодировку символов текстового файла? и Как определить кодировку текста? пришли к выводу, что в лучшем случае это будет трудно.
НО, я нашел Абсолютный минимум, который каждый разработчик программного обеспечения абсолютно, положительно должен знать о Unicode и наборах символов в комментариях, прочитал его и нашел этот драгоценный камень:
UTF-У 8 есть приятный побочный эффект: английский текст в UTF-8 выглядит точно так же, как и в ASCII, поэтому американцы даже не замечают ничего плохого.Только остальной мир должен прыгать через обручи.В частности, Hello, который был U + 0048 U + 0065 U + 006C U + 006C U + 006F, будет сохранен как 48 65 6C 6C 6F, что, вот!это то же самое, что и в ASCII, и в ANSI, и в каждом OEM-наборе символов на планете.
Вся статья короткая и заслуживает прочтения.
Итак,Я решил свою проблему с помощью следующего кода.Поскольку только небольшой объем моих текстовых данных содержит сложные кодовые точки символов, я не возражаю против снижения производительности при обработке исключений, тем более что это нужно было выполнить только один раз.Возможно, есть более умные способы избежать try/catch
, но я не стал его разрабатывать.
public static string ReadAllTextFromFile(string file)
{
const int WindowsCodepage1252 = 1252;
string text;
try
{
var utf8Encoding = Encoding.UTF8;
utf8Encoding.DecoderFallback = DecoderFallback.ExceptionFallback;
text = File.ReadAllText(file, utf8Encoding);
}
catch (DecoderFallbackException dfe)//then text is not entirely valid UTF8, contains Codepage 1252 characters that can't be correctly decoded to UTF8
{
var codepage1252Encoding = Encoding.GetEncoding(WindowsCodepage1252, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback);
text = File.ReadAllText(file, codepage1252Encoding);
}
return text;
}
Стоит также отметить, что класс StreamReader имеет конструкторы, которые принимают определенныйКодирование объекта, и, как я показал, вы можете настроить поведение EncoderFallback / DecoderFallback в соответствии с вашими потребностями.Так что если вам нужен StreamReader или StreamWriter для более тонкой работы, этот подход все еще можно использовать.