Как я игнорирую Маркер Порядка байтов UTF-8 в Сравнениях строк?

У меня есть проблема при сравнении строк в Модульном тесте в C# 4.0 с помощью Visual Studio 2010. Этот тот же тестовый сценарий работает правильно в Visual Studio 2008 (с C# 3.5).

Вот отрывок соответствующих норм:

byte[] rawData = GetData();
string data = Encoding.UTF8.GetString(rawData);

Assert.AreEqual("Constant", data, false, CultureInfo.InvariantCulture);

При отладке этого теста, data строка, кажется, невооруженным глазом содержит точно ту же строку как литерал. Когда я звонил data.ToCharArray(), Я заметил что первый байт строки data значение 65279 который является Маркером Порядка байтов UTF-8. То, что я не понимаю, то, почему Encoding.UTF8.GetString() имеет в наличии этот байт.

Как я добираюсь Encoding.UTF8.GetString() не помещать Маркер Порядка байтов в получившую строку?

Обновление: проблема была этим GetData(), то, которое читает файл из диска, считывает данные с использования файла FileStream.readbytes(). Я исправил это при помощи a StreamReader и преобразование строки к использованию байтов Encoding.UTF8.GetBytes(), который является тем, что это должно было делать во-первых! Спасибо за всю справку.

15
задан Skrud 26 May 2010 в 17:59
поделиться

3 ответа

Я предполагаю, что это потому, что необработанные двоичные данные включают спецификацию. Вы всегда можете удалить спецификацию самостоятельно после декодирования, если вы этого не хотите, но вы должны подумать, должен ли массив байтов учитывать спецификацию для начала.

РЕДАКТИРОВАТЬ: В качестве альтернативы вы можете использовать StreamReader для выполнения декодирования. Вот пример, показывающий преобразование одного и того же массива байтов в два символа с использованием Encoding.GetString или одного символа с помощью StreamReader :

using System;
using System.IO;
using System.Text;

class Test
{
    static void Main()
    {
        byte[] withBom = { 0xef, 0xbb, 0xbf, 0x41 };
        string viaEncoding = Encoding.UTF8.GetString(withBom);
        Console.WriteLine(viaEncoding.Length);

        string viaStreamReader;
        using (StreamReader reader = new StreamReader
               (new MemoryStream(withBom), Encoding.UTF8))
        {
            viaStreamReader = reader.ReadToEnd();           
        }
        Console.WriteLine(viaStreamReader.Length);
    }
}
16
ответ дан 1 December 2019 в 03:43
поделиться

Я полагаю, что лишний символ удаляется, если вы Trim() декодированной строки

-4
ответ дан 1 December 2019 в 03:43
поделиться

Есть немного более эффективный способ сделать это, чем создание StreamReader и MemoryStream:

1) Если вы знаете, что всегда есть BOM

string viaEncoding = Encoding.UTF8.GetString(withBom, 3, withBom.Length - 3);

2) Если не знаете, проверьте:

string viaEncoding;
if (withBom.Length >= 3 && withBom[0] == 0xEF && withBom[1] == 0xBB && withBom[2] == 0xBF)
    viaEncoding = Encoding.UTF8.GetString(withBom, 3, withBom.Length - 3);
else
    viaEncoding = Encoding.UTF8.GetString(withBom);
8
ответ дан 1 December 2019 в 03:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: