Encoding.Default与File.ReadAllText中没有编码不一样?

时间:2009-08-20 11:00:13

标签: .net encoding file-io

(对不起,如果这是一个骗局)

我花了很长时间才试图正确阅读文本文件。

开始使用File.ReadAllText(path)并且搞砸了字符时,我尝试了File.ReadAlltext(path, Encoding)的几个变体,之后我陷入困境,试图分析我的输入文件以确定哪个字节是问题,等等

在绝望中我尝试File.ReadAllText(path, Encoding.Default),这有效!

我现在正在努力理解为什么默认值显然只是默认值,如果你指定它。

(我的剪切测试字符串为+4433ç,我将其作为ANSI保存在记事本中 - 尽管使用瑞士法语区域设置...)

3 个答案:

答案 0 :(得分:10)

Encoding.Default是系统的ANSI代码页。

如果您未指定编码,File.ReadAllText会执行以下操作:

  • 首先检查是否有字节顺序标记(UTF-8,UTF-16或UTF-32)。如果有,它使用字节顺序标记中指定的编码。
  • 否则,它使用UTF-8。

因此,获取系统ANSI代码页的唯一方法是明确指定Encoding.Default。

答案 1 :(得分:3)

UTF8是真正的默认值,仅在自动检测未找到任何编码时使用。因此BOM更重要。请参阅以下详细信息:

ReadAllText(string path) - MSDN:“此方法会尝试自动检测编码”

ReadAllText(string path, Encoding encoding) - MSDN:“此方法会尝试自动检测编码”

来自反射器工具:ReadAllText(path)ReadAllText(path, Encoding.UTF8)相同,因为ReadAllText(path)只调用ReadAllText(path, Encoding.UTF8)。两种方法都以这种方式创建StreamReader:

public StreamReader(string path, Encoding encoding) : this(path, encoding, true, 0x400)
{
}

这意味着它将detectEncodingFromByteOrderMarks设置为true,从而创建StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)。这意味着如果存在字节顺序标记(BOM),它将使用BOM中的编码,如果不存在BOM,则它将使用提供的编码。如果BOM不存在且未提供编码,则它将使用UTF8。因此,在这种情况下, UTF8 是真正的默认值,但请记住,BOM比建议的编码更重要。

// 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's ANSI codepage

答案 2 :(得分:2)

从MSDN,关于字符串ReadAllText(字符串路径)重载:

  

此方法尝试自动检测文件的编码

所以不,它与使用默认编码

不同