У меня есть проблема при сравнении строк в Модульном тесте в 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()
, который является тем, что это должно было делать во-первых! Спасибо за всю справку.
Я предполагаю, что это потому, что необработанные двоичные данные включают спецификацию. Вы всегда можете удалить спецификацию самостоятельно после декодирования, если вы этого не хотите, но вы должны подумать, должен ли массив байтов учитывать спецификацию для начала.
РЕДАКТИРОВАТЬ: В качестве альтернативы вы можете использовать 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);
}
}
Я полагаю, что лишний символ удаляется, если вы Trim() декодированной строки
Есть немного более эффективный способ сделать это, чем создание 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);