为啥 File.ReadAllBytes 结果与使用 File.ReadAllText 时不同?

Posted

技术标签:

【中文标题】为啥 File.ReadAllBytes 结果与使用 File.ReadAllText 时不同?【英文标题】:Why is File.ReadAllBytes result different than when using File.ReadAllText?为什么 File.ReadAllBytes 结果与使用 File.ReadAllText 时不同? 【发布时间】:2014-11-23 23:04:49 【问题描述】:

我有一个内容为“test”的文本文件(UTF-8 编码)。我尝试从此文件中获取字节数组并转换为字符串,但它包含一个奇怪的字符。我使用以下代码:

var path = @"C:\Users\Tester\Desktop\test\test.txt"; // UTF-8

var bytes = File.ReadAllBytes(path);
var contents1 = Encoding.UTF8.GetString(bytes);

var contents2 = File.ReadAllText(path);

Console.WriteLine(contents1); // result is "?test"
Console.WriteLine(contents2); // result is "test"

conents1contents2 不同 - 为什么?

【问题讨论】:

【参考方案1】:

ReadAllText's documentation中所述:

此方法尝试根据字节顺序标记的存在自动检测文件的编码。可以检测编码格式 UTF-8 和 UTF-32(big-endian 和 little-endian)。

所以文件包含 BOM (Byte order mark),ReadAllText 方法正确解释它,而第一个方法只是读取纯字节,根本没有解释它们。

Encoding.GetString 说它只是:

将指定字节数组中的所有字节解码为字符串

(强调我的)。这当然不是完全决定性的,但你的例子表明这是按字面意思理解的。

【讨论】:

所有文档都是垃圾......它不仅会检测 UTF-8 和 UTF-32 but also UTF-16【参考方案2】:

您可能会在文件开头看到 Unicode BOM(字节顺序标记)。 File.ReadAllText 知道如何去掉它,但 Encoding.UTF8 不知道。

【讨论】:

如果您检查第一个字符(int)contents1[0],您将看到该字符是 BOM 字符。更多信息:***.com/questions/6784799/what-is-this-char-65279【参考方案3】:

是 UTF8 编码前缀字符串。它将文件标记为 UTF8 编码。 ReadAllText 不返回它,因为它是一个解析指令。

【讨论】:

以上是关于为啥 File.ReadAllBytes 结果与使用 File.ReadAllText 时不同?的主要内容,如果未能解决你的问题,请参考以下文章

System.IO.File.ReadAllBytes 用于大于 2GB 的文件

为啥CPU使用率不增加?

01.使用File类读写文件

在此算法中将字节数组转换为字符串时出错[重复]

oracle数据库密码文件创建与使

为啥脚本语言(例如 Perl、Python、Ruby)不适合作为 shell 语言? [关闭]