Порядок байтов полосы Mark от строки в C#

Каждый открытый файл имеет связанную позицию. Когда вы читаете (), вы читаете с этой позиции. Например, read(10) считывает первые 10 байт из вновь открытого файла, затем другой read(10) считывает следующие 10 байтов. read() без аргументов считывает все содержимое файла, оставляя позицию файла в конце файла. В следующий раз, когда вы вызываете read(), читать нечего.

Вы можете использовать seek для перемещения позиции файла. Или, вероятно, лучше в вашем случае было бы сделать один read() и сохранить результат для обоих поисков.

42
задан TrueWill 23 August 2009 в 03:39
поделиться

6 ответов

Если переменная xml относится к типу string, значит, вы уже сделали что-то не так - в символьной строке спецификация должна быть представлена ​​не как три отдельных символа, а как одна кодовая точка . Вместо использования DownloadString используйте DownloadData и анализируйте массивы байтов. Синтаксический анализатор XML должен распознавать саму спецификацию и пропускать ее (за исключением автоматического определения кодировки документа как UTF-8).

19
ответ дан 26 November 2019 в 23:15
поделиться

Еще одно универсальное изменение для избавлений от преамбулы BOM UTF-8:

var preamble = Encoding.UTF8.GetPreamble();
if (!functionBytes.Take(preamble.Length).SequenceEqual(preamble))
    preamble = Array.Empty<Byte>();
return Encoding.UTF8.GetString(functionBytes, preamble.Length, functionBytes.Length - preamble.Length);
0
ответ дан 26 November 2019 в 23:15
поделиться

Я решил проблему со следующим кодом

using System.Xml.Linq;

void method()
{
    byte[] bytes = GetXmlBytes();
    XDocument doc;
    using (var stream = new MemoryStream(docBytes))
    {
        doc = XDocument.Load(stream);
    }
 }
0
ответ дан 26 November 2019 в 23:15
поделиться

Передайте байтовый буфер (через DownloadData) в строку Encoding.UTF8.GetString (byte []) , чтобы получить строку, а не загружать буфер как строку. У вас, вероятно, больше проблем с вашим текущим методом, чем просто обрезка метки порядка байтов. Если вы правильно не декодируете его, как я предлагаю здесь, символы Unicode, вероятно, будут неправильно истолкованы, что приведет к повреждению строки.

Изменить : Ответ Мартина лучше, поскольку он позволяет избежать выделения всей строки для XML, который все еще нуждается все равно быть проанализированным. Ответ, который я дал, лучше всего подходит для общих строк, которые не нужно анализировать как XML.

5
ответ дан 26 November 2019 в 23:15
поделиться

У меня были неверные данные теста, что вызвало у меня некоторое замешательство. Основываясь на Как избежать спотыкания о спецификации UTF-8 при чтении файлов Я обнаружил, что это сработало:

private readonly string _byteOrderMarkUtf8 =
    Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());

public string GetXmlResponse(Uri resource)
{
    string xml;

    using (var client = new WebClient())
    {
        client.Encoding = Encoding.UTF8;
        xml = client.DownloadString(resource);
    }

    if (xml.StartsWith(_byteOrderMarkUtf8, StringComparison.Ordinal))
    {
        xml = xml.Remove(0, _byteOrderMarkUtf8.Length);
    }

    return xml;
}

Правильная установка клиентского свойства Encoding сокращает BOM до одного символа. Однако XDocument.Parse по-прежнему не будет читать эту строку. Это самая чистая версия, которую я когда-либо придумал.

44
ответ дан 26 November 2019 в 23:15
поделиться

Это тоже работает

int index = xmlResponse.IndexOf('<');
if (index > 0)
{
    xmlResponse = xmlResponse.Substring(index, xmlResponse.Length - index);
}
31
ответ дан 26 November 2019 в 23:15
поделиться
Другие вопросы по тегам:

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