Encoding.Default не совпадает с отсутствием кодировки в File.ReadAllText?
(Извините, если это обман)
Я уже давно потратил много времени на чтение текстового файла.
Начав с File.ReadAllText(path)
и получив прикрученные символы, я попробовал несколько вариантов File.ReadAlltext(path, Encoding)
, после чего я увязнул, пытаясь проанализировать мои входные файлы, чтобы решить, какой байт был проблемой и т.д.
В отчаянии я пробовал File.ReadAllText(path, Encoding.Default)
, который сработает!
Теперь я пытаюсь понять, почему значение по умолчанию, по-видимому, является только значением по умолчанию, если вы его укажете.
(Моя тестовая строка была +4433ç
, я сохранил ее в блокноте как ANSI - хотя со швейцарскими французскими региональными настройками...)
Ответы
Ответ 1
Encoding.Default - это кодовая страница ANSI системы.
Что делает File.ReadAllText, если вы не указали кодировку:
- Сначала он проверяет наличие метки байтового байта (UTF-8, UTF-16 или UTF-32). Если есть, он использует кодировку, указанную в значке порядка байтов.
- В противном случае он использует UTF-8.
Таким образом, единственный способ получить кодовую страницу системы ANSI - явно указать Encoding.Default.
Ответ 2
UTF8 является реальным значением по умолчанию и используется только тогда, когда автоматическое обнаружение не обнаружено. Поэтому спецификация важнее. См. Подробности ниже:
ReadAllText(string path)
- MSDN: "Этот метод пытается автоматически определить кодировку"
ReadAllText(string path, Encoding encoding)
- MSDN: "Этот метод пытается автоматически обнаружить кодировку"
Из инструмента Reflector: ReadAllText(path)
совпадает с ReadAllText(path, Encoding.UTF8)
, потому что ReadAllText(path)
просто вызывает ReadAllText(path, Encoding.UTF8)
. Оба метода создают StreamReader таким образом:
public StreamReader(string path, Encoding encoding) : this(path, encoding, true, 0x400)
{
}
Это означает, что он создает StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
с функцией detectEncodingFromByteOrderMarks, установленной в true. Это означает, что если присутствует знак порядка байтов (BOM), он будет использовать кодировку из спецификации, если спецификация отсутствует, то она будет использовать предоставленную кодировку. Если спецификация отсутствует и кодировка не предоставляется, она будет использовать UTF8. Таким образом, UTF8 является реальным значением по умолчанию в этом случае, но помните, что спецификация более важна, чем предлагаемая кодировка.
// bom.txt is the file with BOM present. nobom.txt - witout BOM
File.ReadAllText("bom.txt"); // use BOM
File.ReadAllText("bom.txt", Encoding.UTF8); // use BOM
File.ReadAllText("bom.txt", Encoding.Default); // use BOM
File.ReadAllText("nobom.txt"); // use UTF-8
File.ReadAllText("nobom.txt", Encoding.UTF8); // use UTF-8
File.ReadAllText("nobom.txt", Encoding.Default); // use system ANSI codepage
Ответ 3
Из MSDN, о пересылке строки ReadAllText (строка):
Этот метод пытается автоматически определить кодировку файла
Нет, это не то же самое, что использовать кодировку по умолчанию