Чтение частей файла Xml через поток вместо одного

Итак, я работал над старым фрагментом кода для проекта. Мне удалось оптимизировать его для 64-битного использования. Но есть только 1 проблема. При использовании XmlSerializer.Deserialize он ломается, потому что входной текст/десериализованные данные СЛИШКОМ БОЛЬШИЕ. (переполняется/превышает ограничение в 2 ГБ).

Я пытался найти исправление, но ни один ответ не помог.

Вот код, о котором идет речь.

if (File.Exists(dir + "/" + fileName))
{
    string XmlString = File.ReadAllText(dir + "/" + fileName, Encoding.UTF8);
    BXML_LIST deserialized;
    using (MemoryStream input = new MemoryStream(Encoding.UTF8.GetBytes(XmlString)))
    {
        using (XmlTextReader xmlTextReader = new XmlTextReader(input))
        {
            xmlTextReader.Normalization = false;
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(BXML_LIST));
            deserialized = (BXML_LIST)xmlSerializer.Deserialize(xmlTextReader);
        }
    }
    xml_list.Add(deserialized);
}

После многих вопросов, заданных здесь, я подумал, что мог бы использовать метод для разделения файла xml (СОХРАНЯЯ ТАКОЙ ТИП BXML_LIST), затем десериализовать его и закончить: Объедините его, чтобы он соответствовал исходному содержимому, чтобы избежать ошибки переполнения при десериализации весь файл.

Дело в том, что я понятия не имею, как это реализовать. Любая помощь или руководство были бы потрясающими!

// Редактировать 1:

Я нашел фрагмент кода с другого сайта, не знаю, может ли это быть надежным способом объединить разделенный файл xml:

var xml1 = XDocument.Load("file1.xml");
var xml2 = XDocument.Load("file2.xml");
//Combine and remove duplicates
var combinedUnique = xml1.Descendants("AllNodes")
                          .Union(xml2.Descendants("AllNodes"));
//Combine and keep duplicates
var combinedWithDups = xml1.Descendants("AllNodes")
                           .Concat(xml2.Descendants("AllNodes"));

person Endless    schedule 13.12.2020    source источник
comment
Чтобы помочь вам, нам нужно знать структуру вашего XML и видеть код BXML_LIST. Опубликуйте их.   -  person Alexander Petrov    schedule 13.12.2020


Ответы (1)


Ваш код вызывает у меня мурашки, вы так неэффективно используете память.

string XmlString = File.ReadAllText - Здесь вы загружаете весь файл в память в первый раз.

Encoding.UTF8.GetBytes(XmlString) - Здесь вы тратите память на одни и те же данные во второй раз.

new MemoryStream(...) - Здесь вы тратите память на одни и те же данные в третий раз.

xmlSerializer.Deserialize - Здесь снова тратится память на десериализованные данные. Но от этого никуда не деться.


Пишите вот так

using (XmlReader xmlReader = XmlReader.Create(dir + "/" + fileName))
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(BXML_LIST));
    deserialized = (BXML_LIST)xmlSerializer.Deserialize(xmlReader);
}

В этом случае xmlSerializer будет считывать данные из файла с помощью xmlReader потоком, частями.

Возможно, этого может быть достаточно для решения вашей проблемы.

person Alexander Petrov    schedule 13.12.2020
comment
Творит чудеса. - person Endless; 13.12.2020