防止 File.WriteAllText 写入双字节顺序标记 (BOM)?

Prevent File.WriteAllText to write double Byte-Order Mark (BOM)?

在下面的示例中,如果 (string) 文本以 BOM 开头,File.writeAllText() 将添加 另一个 ,写入 两个 BOM .

我想把文字写两遍:

  1. 完全没有 BOM
  2. 具有单个 BOM(如果适用于编码)

实现此目的的规范方法是什么?

HttpWebResponse response = ...
Byte[] byte = ... // bytes from response possibly including BOM 

var encoding = Encoding.GetEncoding(
                    response.get_CharacterSet(),
                    new EncoderExceptionFallback(),
                    new DecoderExceptionFallback()
               );
string text = encoding.GetString(bytes); // will preserve BOM if any
System.IO.File.WriteAllText(fileName, text, encoding);

你正在解码然后重新编码文件...这很没用。

Encoding class 中有一个 GetPreamble() 方法 returns 序言(称为 utf-* 编码的 BOM),在 byte[].然后我们可以检查收到的 bytes 数组是否已经有这个前缀。然后根据这些信息我们可以编写文件的两个版本,必要时添加或删除前缀。

var encoding = Encoding.GetEncoding(response.CharacterSet, new EncoderExceptionFallback(), new DecoderExceptionFallback());

// This will throw if the file is wrongly encoded
encoding.GetCharCount(bytes);

byte[] preamble = encoding.GetPreamble();

bool hasPreamble = bytes.Take(preamble.Length).SequenceEqual(preamble);

if (hasPreamble)
{
    File.WriteAllBytes("WithPreambleFile.txt", bytes);

    using (var fs = File.OpenWrite("WithoutPreamble.txt"))
    {
        fs.Write(bytes, preamble.Length, bytes.Length - preamble.Length);
    }
}
else
{
    File.WriteAllBytes("WithoutPreambleFile.txt", bytes);

    using (var fs = File.OpenWrite("WithPreamble.txt"))
    {
        fs.Write(preamble, 0, preamble.Length);
        fs.Write(bytes, 0, bytes.Length);
    }
}