Почему текст из Assembly.GetManifestResourceStream () начинается с трех ненужных символов?

У меня есть файл SQL, добавленный в мой проект VS.NET 2008 в качестве встроенного ресурса. Всякий раз, когда я использую следующий код для чтения содержимого файла, возвращаемая строка всегда начинается с трех ненужных символов, а затем с ожидаемого текста. Я предполагаю, что это как-то связано с используемым мной Encoding.Default, но это всего лишь предположение. Почему этот текст продолжает появляться? Должен ли я просто обрезать первые три символа или есть более осознанный подход?

public string GetUpdateRestoreSchemaScript()
{
    var type = GetType();
    var a = Assembly.GetAssembly(type);
    var script = "UpdateRestoreSchema.sql";
    var resourceName = String.Concat(type.Namespace, ".", script);
    using(Stream stream = a.GetManifestResourceStream(resourceName))
    {
        byte[] buffer = new byte[stream.Length];
        stream.Read(buffer, 0, buffer.Length);
        // UPDATE: Should be Encoding.UTF8
        return Encoding.Default.GetString(buffer);
    }
}

Обновление: теперь я знаю, что мой код работает должным образом, если я просто изменю последнюю строку, чтобы вернуть строку в кодировке UTF-8. Это всегда будет верно для этого встроенного файла, но всегда ли это будет верно? Есть ли способ протестировать любой буфер, чтобы определить его кодировку?

Ответов (3)

Решение

Вероятно, файл находится в кодировке utf-8 и кодировке по умолчанию ASCII. Почему вы не используете конкретную кодировку?

Отредактируйте, чтобы ответить на комментарий:

Чтобы угадать кодировку файла, вы можете найти спецификацию в начале потока. Если он существует, это помогает, если нет, вы можете только догадываться или спрашивать пользователя.

У меня была такая же проблема в net.core. Вы можете позволить streamreader выполнять кодирование.

 using (var stream = = a.GetManifestResourceStream(resourceName))
    using (var reader = new StreamReader(stream))
       return reader.ReadToEnd();

если вы попытаетесь загрузить xml из сборки, вам действительно нужно проверить и пропустить байты отметки порядка байтов (меня сбили с ума):

....
byte[] data;
using (var stream = assembly.GetManifestResourceStream(filename))
{
    var length = stream.Length;
    data = new byte[length];
    stream.Read(data, 0, (int) length);
}
if (!HasUtf8ByteOrderMark(data))
{
    throw new InvalidOperationException("Expected UTF8 byte order mark EF BB BF");
}
return Encoding.UTF8.GetChars(data.Skip(3).ToArray());

А также

static bool HasUtf8ByteOrderMark(byte[] data)
{
    var bom = new byte[] { 0xEF, 0xBB, 0xBF };
    return data[0] == bom[0] && data[1] == bom[1] && data[2] == bom[2];
}

Больше информации здесь