【问题标题】: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。

如何区分它们?

【问题讨论】:

    标签: c# utf-8 filestream streamreader byte-order-mark


    【解决方案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)。
    猜你喜欢
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    相关资源
    最近更新 更多