2012-11-16 28 views
11

Ben ancak hafıza İstisna dışına atmakOku Büyük TXT Dosyası, Bellek İstisna dışında

var file = new StreamReader(_filePath).ReadToEnd(); 
var lines = file.Split(new[] { '\n' }); 

kullanmak 500 MB, İlk olan büyük TXT dosya boyutunu okumak istiyorum o zaman satır satır okumaya çalıştım ama yine yaklaşık 1,5 milyon satırları okuduktan sonra bellek İstisna

using (StreamReader r = new StreamReader(_filePath)) 
     {    
      while ((line = r.ReadLine()) != null)    
       _lines.Add(line);    
     } 

dışarı atmak ya da ben

foreach (var l in File.ReadLines(_filePath)) 
      { 
       _lines.Add(l); 
      } 
kullanılan

ama Yine

türü 'System.OutOfMemoryException' mscorlib.dll oluştu bir durum aldı ama

My Makine bunun böylece ram 8GB ile güçlü bir makinedir kullanıcı kodu işlenmedi benim makine problemim olmamalı.

p.s: Bu dosyayı NotePadd ++ 'da açmaya çalıştım ve' dosya açılmayacak kadar büyük 'bir istisna aldım.

+2

Soru nedir? Sadece bir şeyleri tarif ediyorsun. –

+1

Koleksiyondaki her şeyi saklamaya yarayan nokta nedir? – CyberDude

+0

@AlvinWong sorunu outofMemory Özel Durumunu almamın nedeni budur. Bunu nasıl çözebilirim? – Behnam

cevap

30

Yalnızca IEnumerable<string> değerini döndüren File.ReadLines kullanın ve tüm satırları bir kerede belleğe yüklemez.

foreach (var line in File.ReadLines(_filePath)) 
{ 
    //Don't put "line" into a list or collection. 
    //Just make your processing on it. 
} 
+0

Sadece boş döngü foreach kullanın (File.ReadLines (_filePath) içinde var satırı olsa bile) aynı sorun {} – Behnam

+0

@ Beehnam programınızın diğer bölümlerinden bu hatayı almadığınızdan emin misiniz? . Bunu boş bir çözümde deneyin. –

+0

Sadece bir kod satırı foreach satırı (File.ReadLines (_filePath) içinde var satırı) {} olan bir Console uygulaması oluşturdum, ancak yine bir istisna oluşturuyor. – Behnam

2

Özel durumun nedeni, _lines koleksiyonunu büyütmekle birlikte büyük dosya okumamak gibi görünüyor. Satırı okuyorsunuz ve adding to some collection _lines which will be taking memory and causing out of memory execption. Sadece gerekli satırları _lines koleksiyonuna koymak için filtreler uygulayabilirsiniz.

+0

Verileri _lines koleksiyonuna ekleyen satırı kaldırıyorum ancak sorun hala var. – Behnam

+1

Şimdi hangi istisna atar? – Adil

+0

OutofMemoryException – Behnam

1

Düzenleme: bellekteki dosyanın tamamını yükleyerek

nesneler büyümeye neden olacak ve bunun bir nesne için yeterli bitişik bellek ayrılamıyor eğer .net OOM istisnalar atar.

Yanıt hala aynıdır, dosyayı akışa almanız gerekir, içeriğin tamamını okumazsınız. Bu, uygulamanızın yeniden çalıştırılmasını gerektirebilir, ancak IEnumerable<> yöntemlerini kullanarak, iş süreçlerini uygulamaların farklı alanlarında biriktirebilir ve işlemleri erteleyebilirsiniz.


8GB RAM ile "güçlü" makine

8. daha büyük 500 gibi, bellekte 500GB dosyasını depolamak mümkün olmayacak (artı işletim sistemi olarak 8 alamadım bazı tutuyor olacak, tüm bellek atayamazsınız. Net, 32-bit bir 2GB sınırına sahip, dosyayı açarak ve depolamayı saklamak veriyi iki kez tutacak, bir nesne boyutu yükü vardır ....)

Tüm işlemi işlemek için belleğe yükleyemezsiniz, dosyayı işlemeniz sırasında yürütmeniz gerekir.

+0

cevabınız için çok teşekkürler, ancak 500MB değil 500MB – Behnam

+0

İkinci yaklaşımımda StreamReader'ı kullanmayı ve hatta _lines.Add (satır) öğesini kaldırmayı denedim; satır, OutOfMemoryException alıyorum. Bu yüzden, akışla ne demek istediğinizi tam olarak anlamadım. – Behnam

+0

Belki "hat" sonlandırıcı olması gereken değil midir? Hatlar \ r AND \ n ile sonlandırılmazsa, dahili işlevler muhtemelen tüm dosyayı belleğe okuyacaktır, değil mi? – igrimpe

İlgili konular