如何检测 .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指令集或程序集引用?)该问题如何解决?

.net StreamReader .Readline报内存溢出OutOfMemory,求助!!

VB.net Streamreader用于不同的潜艇

使用vb.net保存数据时如何检测是不是有相同的单词