如何检测 .NET StreamReader 是不是在底层流上找到了 UTF8 BOM?
Posted
技术标签:
【中文标题】如何检测 .NET StreamReader 是不是在底层流上找到了 UTF8 BOM?【英文标题】:How can I detect if a .NET StreamReader found a UTF8 BOM on the underlying stream?如何检测 .NET StreamReader 是否在底层流上找到了 UTF8 BOM? 【发布时间】:2011-06-28 02:01:00 【问题描述】:我得到一个FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.ReadWrite)
,然后是一个StreamReader(stream,true)
。
有没有办法检查流是否以 UTF8 BOM 开头? 我注意到没有 BOM 的文件被 StreamReader 读取为 UTF8。
如何区分它们?
【问题讨论】:
【参考方案1】:比起硬编码字节,使用 API 更漂亮
public string ConvertFromUtf8(byte[] bytes)
var enc = new UTF8Encoding(true);
var preamble = enc.GetPreamble();
if (preamble.Where((p, i) => p != bytes[i]).Any())
throw new ArgumentException("Not utf8-BOM");
return enc.GetString(bytes.Skip(preamble.Length).ToArray());
【讨论】:
@carlo-v-dango,我建议添加某种空检查,因为如果文件为空,字节可能为空。if (preamble.Where((p, i) => bytes.Length > i && p != bytes[i]).Any())
或任何漂浮在您船上的东西。【参考方案2】:
这有帮助吗?你检查文件的前三个字节:
public static void Main(string[] args)
FileStream fs = new FileStream("spork.txt", FileMode.Open);
byte[] bits = new byte[3];
fs.Read(bits, 0, 3);
// UTF8 byte order mark is: 0xEF,0xBB,0xBF
if (bits[0] == 0xEF && bits[1] == 0xBB && bits[2] == 0xBF)
Console.ReadLine();
【讨论】:
确保将 FileStream 放入 using 语句,因为它是一次性对象。 按照惯例,最好使用前导码而不是硬编码的字节值。【参考方案3】:您可以通过使用无 BOM 的 UTF8 编码对其进行初始化并检查 CurrentEncoding
在第一次读取后是否发生变化来检测 StreamReader
是否遇到 BOM。
var utf8NoBom = new UTF8Encoding(false);
using (var reader = new StreamReader(file, utf8NoBom))
reader.Read();
if (Equals(reader.CurrentEncoding, utf8NoBom))
Console.WriteLine("No BOM");
else
Console.WriteLine("BOM detected");
【讨论】:
我从没想过这会奏效。谢谢!事实相反,这真是太糟糕了。您不能传递 int UTF8Encoding(true) 并让它返回 UTF8Encoding(false)。以上是关于如何检测 .NET StreamReader 是不是在底层流上找到了 UTF8 BOM?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 .net StreamReader 打开已打开的文件?
C# 文件流 streamreader如何读取文本指定行的数据?
找不到类型或命名空间为"StreamReader"(是不是缺少using指令集或程序集引用?)该问题如何解决?