2016-03-29 26 views
2

Bir URl aracılığıyla 3 GB XML dosyasını okumaya çalışıyorum ve tüm işleri veri kümesinde saklıyorum. XML şöyle görünür:DataSet üzerinde büyük XML yükleniyor (OutOfMemory Exception)

<?xml version="1.0"?> 
    <feed total="1621473"> 
     <job> 
     <title><![CDATA[Certified Medical Assistant]]></title> 
     <date>2016-03-25 14:19:38</date> 
     <referencenumber>2089677765</referencenumber> 
     <url><![CDATA[http://www.jobs2careers.com/click.php?id=2089677765.1347]]></url> 
     <company><![CDATA[Broadway Medical Clinic]]></company> 
     <city>Portland</city> 
     <state>OR</state> 
     <zip>97213</zip> 
    </job> 
    <job> 
     <title><![CDATA[Certified Medical Assistant]]></title> 
     <date>2016-03-25 14:19:38</date> 
     <referencenumber>2089677765</referencenumber> 
     <url><![CDATA[http://www.jobs2careers.com/click.php?id=2089677765.1347]]></url> 
     <company><![CDATA[Broadway Medical Clinic]]></company> 
     <city>Portland</city> 
     <state>OR</state> 
     <zip>97213</zip> 
    </job> 
    </feed> 

Bu benim kod

XmlDocument doc = new XmlDocument(); 
      doc.Load(url); 
      DataSet ds = new DataSet(); 
      XmlNodeReader xmlReader = new XmlNodeReader(doc); 

      while (xmlReader.ReadToFollowing("job")) 
      { 
       ds.ReadXml(xmlReader); 
      } 

olduğu Ama ciltli istisna dışında hafızası var. google üzerine Gözatılacak ve bu bulundu: hala

DataSet ds = new DataSet(); 
     FileStream filestream = File.OpenRead(url); 
     BufferedStream buffered = new BufferedStream(filestream); 
     ds.ReadXml(buffered); 

aynı istisna. Ben de XmlTextReader hakkında okudum ama benim durumumda bunu nasıl kullanacağımı bilmiyorum. Neden istisna alıyorum biliyorum ama nasıl üstesinden geleceğini bilmiyorum.Teşekkürler

+0

Özel durum ayrıntıları nedir? Ben 'OutOfMemoryException' atıyor XmlDocument olabilir şüpheli. Bunun nedeni, büyük bir XML dosyası oluşturmak için bazı kodları bir araya getirdiğimden ve yeterli veri üretmeden önce, oluşturduğum XmlDocument nesnesinin atmasıdır. Belki de düğümlerin iç koleksiyonu ile ilgilidir ({System.Collections.ListDictionaryInternal.NodeKeyValueCollection}). – Stringfellow

+0

Ne çıktı istiyorsunuz? Anlamıyorum "tüm işleri boğaz". –

+0

@MichaelKay: Benim kötü, düzenlenmiş. Tüm işleri veri kümesinde saklamak istiyorum, böylece hepsini bir veritabanı tablosunda saklayabilirim. – Iman

cevap

1

, her seferinde mi

Nasıl yapılır: Akış bir DataSet kullanarak Büyük XML Belgelerinin https://msdn.microsoft.com/en-us/library/bb387013.aspx

 List<XElement> jobs = new List<XElement>(); 
     using (XmlReader reader = XmlReader.Create(filePath)) 
     { 
      XElement job; 
      reader.MoveToContent(); 
      while (reader.Read()) 
      { 
       if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "job")) 
       { 
        job = XElement.ReadFrom(reader) as XElement; 
        jobs.Add(job); 

        if (jobs.Count >= 1000) 
        { 
         // TODO: write batch to database 
         jobs.Clear(); 
        } 
       } 
      } 

      if (jobs.Count > 0) 
      { 
       // TODO: write remainder to database 
       jobs.Clear(); 
      } 

     } 

Alternatif ait Transform gerçekleştirin.

 DataSet ds = new DataSet(); 
     using (XmlReader reader = XmlReader.Create(filePath)) 
     { 
      reader.MoveToContent(); 
      while (reader.Read()) 
      { 
       if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "job")) 
       { 
        ds.ReadXml(reader); 

        DataTable dt = ds.Tables["job"]; 
        if (dt.Rows.Count >= 1000) 
        { 
         // TODO: write batch to database 
         dt.Rows.Clear(); 
        } 
       } 
      } 

      if (ds.Tables["job"].Rows.Count > 0) 
      { 
       // TODO: write remainder to database 
       ds.Tables["job"].Rows.Clear(); 
      } 
     } 
+0

Zaman ayırdığınız için teşekkür ederiz. Ve bu kodu kullanarak Veri kümemi nasıl dolduracağım? – Iman

+0

Alternatif ekledim. DataSet'i yüklemekle ilgili mi demek istediniz? 3 GB'lık bir dosyanın tamamını bellek sorunuyla karşılaşmadan DataSet'e yükleyip yükleyemeyeceğinizi bilmiyorum. Ayrıca, toplu işlemle, parça işlemenin kısmen başarısız olması durumunda bir 'özgeçmiş' senaryosunu etkinleştirebilirsiniz. – Stringfellow

+0

Veri kümesi, 2 satır tarafından doldurulur ve bundan sonra ilk if ifadesi yanlış olur, herhangi bir fikir neden? hala üzerinde çalışıyor. Çözümünüz sağlam geliyor, size bildireceğim – Iman

0

doc.Load() tüm dosyayı okuyacak ve hata verecek. XmlNodeReader sizin için gerçekten bir şey yapmayacaktır. Deneyin bu

using System; 
 
using System.Collections.Generic; 
 
using System.Linq; 
 
using System.Text; 
 
using System.Xml; 
 
using System.Xml.Linq; 
 
using System.Data; 
 

 
namespace ConsoleApplication1 
 
{ 
 
    class Program 
 
    { 
 
     const string url = @"c:\temp\test.xml"; 
 
     static void Main(string[] args) 
 
     { 
 
      int count = 0; 
 
      DataSet ds = new DataSet(); 
 
      XmlReader xmlReader = XmlReader.Create(url); 
 
      xmlReader.MoveToContent(); 
 
      try 
 
      { 
 
       while (!xmlReader.EOF) 
 
       { 
 
        count++; 
 
        xmlReader.ReadToFollowing("job"); 
 
        if (!xmlReader.EOF) 
 
        { 
 
         ds.ReadXml(xmlReader); 
 
        } 
 
       } 
 
      } 
 
      catch (Exception ex) 
 
      { 
 
       Console.WriteLine("Count : {0}", count); 
 
       Console.ReadLine(); 
 
      } 
 
      
 
     } 
 
    } 
 

 
}
yüzden ne olursa olsun toplu düzenliyor silinebilir nasıl yükleme gruplar hakkında ve veritabanına her parti yazmak yerine DataSet veya diğer kaba tüm dosya yüklemek çalışmakla

+0

Hala ds.ReadXml() – Iman

+0

üzerinde System.OutOfMemoryException alıyorum Bazı yazım hatası hataları kaldırmak için kod güncelleştirildi. Sorunu çözecek mi emin değilim. Kaç tane satır okuduğunuzu biliyor musunuz? İş öğeleri istisnadan önce okunur mu? – jdweng

+0

Zaman ayırdığınız için teşekkür ederiz. Hala aynı istisna yok. Hata ayıklamaya çalıştım ama hayır kaç satır okuduğumu bilmeme izin vermiyor. Sanırım xml dosyasını parçalara ayırmanın ve onları tek tek okuyabilmenin ya da dosyayı bir tampondan okuyabilmenin bir yolu olmalı, böylece tüm dosya bir seferde yüklenmeyecek. Sadece nasıl başaracağımı bilmiyorum. – Iman

İlgili konular