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 (строка):

Этот метод пытается автоматически определить кодировку файла

Нет, это не то же самое, что использовать кодировку по умолчанию