Dot-Net

Encoding.UTF8.GetString 不考慮 Preamble/BOM

  • July 28, 2012

在 .NET 中,我正在嘗試使用Encoding.UTF8.GetString方法,該方法採用字節數組並將其轉換為string.

看起來此方法忽略了BOM(字節順序標記),它可能是 UTF8 字元串的合法二進製表示的一部分,並將其視為字元。

我知道我可以TextReader根據需要使用 a 來消化 BOM,但我認為 GetString 方法應該是某種使我們的程式碼更短的宏。

我錯過了什麼嗎?這是故意的嗎?

這是一個複制程式碼:

static void Main(string[] args)
{
   string s1 = "abc";
   byte[] abcWithBom;
   using (var ms = new MemoryStream())
   using (var sw = new StreamWriter(ms, new UTF8Encoding(true)))
   {
       sw.Write(s1);
       sw.Flush();
       abcWithBom = ms.ToArray();
       Console.WriteLine(FormatArray(abcWithBom)); // ef, bb, bf, 61, 62, 63
   }

   byte[] abcWithoutBom;
   using (var ms = new MemoryStream())
   using (var sw = new StreamWriter(ms, new UTF8Encoding(false)))
   {
       sw.Write(s1);
       sw.Flush();
       abcWithoutBom = ms.ToArray();
       Console.WriteLine(FormatArray(abcWithoutBom)); // 61, 62, 63
   }

   var restore1 = Encoding.UTF8.GetString(abcWithoutBom);
   Console.WriteLine(restore1.Length); // 3
   Console.WriteLine(restore1); // abc

   var restore2 = Encoding.UTF8.GetString(abcWithBom);
   Console.WriteLine(restore2.Length); // 4 (!)
   Console.WriteLine(restore2); // ?abc
}

private static string FormatArray(byte[] bytes1)
{
   return string.Join(", ", from b in bytes1 select b.ToString("x"));
}

看起來此方法忽略了 BOM(字節順序標記),它可能是 UTF8 字元串的合法二進製表示的一部分,並將其視為字元。

它看起來根本沒有“忽略”它 - 它忠實地將其轉換為 BOM 字元。畢竟就是這樣。

如果你想讓你的程式碼忽略它轉換的任何字元串中的 BOM,這取決於你做…或使用StreamReader.

請注意,如果您使用Encoding.GetBytes後跟Encoding.GetString 使用StreamWriter後跟StreamReader,兩種形式都將生成然後吞下或不生成 BOM 。只有當您將 a StreamWriter(使用Encoding.GetPreamble)與直接Encoding.GetString呼叫混合使用時,您才會得到“額外”字元。

引用自:https://stackoverflow.com/questions/11701341