Я пытаюсь сериализовать XML-файл, и я столкнулся с некоторой проблемой. Посмотрите ниже в моем файле примера xml:xmlreader читает каждый второй шаг
<Information xmlns="dis">
<SOS.Alert>
<signal>4</signal>
<tresh>RTX</tresh>
<obb>GGHUI</obb>
</SOS.Alert>
<SOS.Alert>
<signal>3</signal>
<tresh>RTR</tresh>
<obb>GGH</obb>
</SOS.Alert>
<SOS.Alert>
<signal>20</signal>
<tresh>WWRTX</tresh>
<obb>BBHUI</obb>
</SOS.Alert>
<SOS.Alert>
<signal>13</signal>
<tresh>DRTR</tresh>
<obb>GFH</obb>
</SOS.Alert>
....
</Information>
Проблема в том, что она пропускает каждую секунду. Так что, если мы имеем 4 входа, как и выше будет сериализовать только два:
<SOS.Alert>
<signal>4</signal>
<tresh>RTX</tresh>
<obb>GGHUI</obb>
</SOS.Alert>
<SOS.Alert>
<signal>20</signal>
<tresh>WWRTX</tresh>
<obb>BBHUI</obb>
</SOS.Alert>
Это код, я использую:
Me.xmlreader = New XmlTextReader(inputFileName)
Me.xmlreader.WhitespaceHandling = WhitespaceHandling.None
While (Me.xmlreader.Read())
If ((Me.xmlreader.Name = "SOS.Alert") And (Me.xmlreader.NodeType = XmlNodeType.Element) And (Me.xmlreader.IsStartElement())) Then
Me.data.MyList.Add(xmlreader.ReadOuterXml)
End If
End While
Обратите внимание, что я хочу остаться с XMLTeamReader, потому что я действую на большой XML-файл размером более 1,5 ГБ, а XDocument, XElement и другие не рассматриваются, поскольку они загружают весь XML в память, поэтому исключение OutoOfMemory.
Использование моего старого кода завершает (конечно же, второй шаг) на 221155-й строке. Я внедрил ваш код, и через некоторое время я получил это исключение: «В mscorlib.dl произошло необработанное исключение типа« System.OutOfMemoryException ». Во всяком случае, я проверил первые пары строк, и кажется, что он принимает каждую строку. Как избежать этой ошибки? – unknown
Вы читаете более 1,5 ГБ данных и сохраняете их в 'data' (' Me.data.MyList.Add'). Возможно, MyList не сможет справиться с этим. Помните, что при использовании старого кода ваш список будет содержать половину того, что он содержит, используя новый код. Возможно, вы можете изменить свою программу таким образом, чтобы вы обрабатывали результат непосредственно перед его хранением в списке; в этом случае вам не нужно столько памяти. Вы можете использовать профилировщик памяти, какой объект (ы) несет/несет ответственность за чрезмерную загрузку памяти. Если у вас его нет: есть пробные версии. Затем попробуйте исправить (или попросить о помощи еще раз). – Sjips
С размером файла, который вы используете, вы, вероятно, проблема с большой кучей объектов (LOH). Эта часть кучи собирается GC, но не дефрагментирована. Во время добавления элементов в список емкость увеличивается за счет выделения новой памяти с двойным пространством, а массив/список копируется. Решением для этого является предварительное выделение ожидаемого количества элементов в конструкторе списка ('Dim list As New List (Of String) (1000000)'). Вам может потребоваться более высокая емкость, но помните, что массивы (а списки - массивы) не могут выходить за пределы 2 ГБ, даже на x64 (.Net4.5 имеет решение). – Sjips