2015-01-07 2 views
1

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 개 입력 그래서 만약 위의 두 직렬화 될 것 같은 :

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 

주 I가 작동하고 있기 때문에 내가 XMLTeamReader와 함께 있고 싶어 : 이것은 내가 사용하고있는 코드가

<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> 

1.5GB 이상의 큰 XML 파일과 XDocument, XElement 및 기타는 전체 XML을 메모리에로드 할 때 고려되지 않습니다. 따라서 OutoOfMemory 예외입니다.

답변

1

나는이 문제가 ReadOuterXml 호출이라고 생각합니다. "통화 후 위치"를 보여줍니다이 MSDN 문서, 특히 비고 테이블에서보세요 : http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.readouterxml%28v=vs.110%29.aspx

그것은 보여줍니다이 XML과 :

<item1>text1</item1><item2>text2</item2> 

항목 1 내에서, 것 동안 ReadOuterXml를 호출하는 경우 리더를 Item2로 이동하십시오. 이것은 루프 내에서 발생하기 때문에 독자가 다시 앞으로 진행하고 시작 태그를 지나서 두 번째 항목으로 이동합니다. 이로 인해 "건너 뜁니다."

0

ReadOuterXml 다음에는 독자가 이미 다음 노드 인 두 번째 SOS.Alert에 있습니다. 그러나 Me.xmlreader.Read() 호출 때문에 xml의 다음 항목은 signal으로 읽습니다. 그것은 너무 먼 것이다. 이제 세 번째 SOS.Alert를 볼 수있는 노드 util을 읽습니다. 아래 코드가 필요하다고 생각합니다. 첫 번째 SOS.Alert를 찾은 후에는 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 
       While ((Me.xmlreader.Name = "SOS.Alert") And (Me.xmlreader.NodeType = XmlNodeType.Element) And (Me.xmlreader.IsStartElement())) 
        Me.data.MyList.Add(xmlreader.ReadOuterXml) 
       End While 
      End If 
     End While 
+0

내 오래된 코드를 사용하면 221155 번째 줄에서 마무리됩니다 (물론 두 번째 단계 문제 포함). 내가 코드를 구현하고 잠시 후이 예외가 발생했습니다. "처리되지 않은 'System.OutOfMemoryException'형식의 예외가 mscorlib.dl에서 발생했습니다." 어쨌든 나는 처음 몇 행을 확인하고 모든 행을 취하는 것 같습니다. 그 오류를 피하는 방법? – unknown

+0

1.5GB 이상의 데이터를 읽고'data' ('Me.data.MyList.Add')에 저장하십시오. MyList가 처리 할 수없는 경우 일 수 있습니다. 이전 코드를 사용할 때 목록에는 새 코드를 사용하여 포함 된 내용의 절반이 포함됩니다. 결과를 목록에 저장하기 전에 직접 처리하는 방식으로 프로그램을 변경할 수 있습니다. 이 경우에는 많은 메모리가 필요하지 않습니다. 과도한 메모리 부하를 담당하는 메모리 프로파일 러를 사용할 수 있습니다. 가지고 있지 않다면 시험판이 있습니다. 그런 다음 문제를 해결하거나 다시 도움을 청하십시오. – Sjips

+0

사용중인 파일 크기가 큰 개체 힙 (LOH) 문제 일 수 있습니다. 이 힙 부분은 GC에 의해 수집되지만 조각 모음은 수행되지 않습니다. 목록에 항목을 추가하는 동안 새 메모리를 두 배로 할당하여 용량을 늘리고 배열/목록을 복사합니다. 이에 대한 해결책은 List 생성자 ('Dim list As New List Of (String) (1000000)')에 예상되는 항목 수를 미리 할당하는 것입니다. 더 많은 용량이 필요할 수도 있지만, 배열 (및 목록은 배열)은 x64에서도 (심지어 Net4.5에는 솔루션이 있음) 2GB를 초과 할 수 없음을 기억하십시오. – Sjips

관련 문제