Encoding.UTF8.GetString не учитывает Preamble/BOM

В.NET я пытаюсь использовать метод Encoding.UTF8.GetString, который берет массив байтов и преобразует его в string.

Похоже, что этот метод игнорирует BOM (Byte Order Mark), который может быть частью допустимого двоичного представления строки UTF8 и воспринимает его как символ.

Я знаю, что могу использовать TextReaderдля переваривания спецификации по мере необходимости, но я подумал, что метод 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"));
}

25
задан Charles 28 July 2012 в 20:32
поделиться