2012-11-16 40 views
11

我想讀大TXT文件大小爲500 MB, 首先我用瀏覽大TXT文件,內存溢出異常

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

但它拋出內存異常的話,我想逐行讀取但再次閱讀約150萬線後拋出內存異常

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

,或者我用

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

但我再次收到

類型「System.OutOfMemoryException的」發生在 mscorlib.dll中的一個例外,但在用戶代碼中沒有處理

我的機器是強大的機RAM的8GB所以不應該是我的機器問題。

p.s:我試圖在NotePadd ++中打開這個文件,我收到'文件太大而無法打開'異常。

+2

什麼問題?你只是在描述一些事情。 –

+1

將所有內容存儲在集合中的要點是什麼? – CyberDude

+0

@AlvinWong問題是爲什麼我收到OutofMemory異常,我可以如何解決它 – Behnam

回答

30

只需使用File.ReadLines即可返回IEnumerable<string>並且不會一次將所有行加載到內存中。

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

即使只使用空循環foreach(File.ReadLines(_filePath)中的var行),也會出現同樣的問題{} – Behnam

+0

@Behnam您確定您沒有從程序的其他部分收到此錯誤。試試這個空的解決方案。 –

+0

我剛剛創建了一個控制檯應用程序,它只是一行代碼foreach(var line in File.ReadLines(_filePath)){},但它再次創建異常。 – Behnam

2

異常的原因似乎越來越多_lines收集但不讀大文件。您正在閱讀線路和adding to some collection _lines which will be taking memory and causing out of memory execption。您可以應用過濾器,只將所需的行放到_lines集合中。

+0

我只是刪除添加數據到_lines集合的行,但問題依然存在。 – Behnam

+1

現在拋出什麼異常? – Adil

+0

OutofMemoryException – Behnam

1

編輯:

加載在內存中的整個文件將導致物體增長,.NET將拋出OOM異常,如果它不能爲對象分配足夠的連續內存。

答案還是一樣,你需要流式傳輸文件,而不是讀取整個內容。這可能需要重新構建應用程序,但使用IEnumerable<>方法可以在應用程序的不同區域中疊加業務流程並推遲處理。


A「強大」的機器與8GB的內存是不是要能夠在內存中存儲500GB的文件,500比8大(加上你沒有得到8操作系統將持有一些,你不能分配.Net中的所有內存,32位有2GB的限制,打開文件和存儲行將保存數據兩次,有一個對象大小開銷....)

您無法將整個內容加載到內存中進行處理,您將不得不通過處理對文件進行流式處理。

+0

非常感謝您的回答,但它的500MB不是500GB – Behnam

+0

在我的第二種方法中,我嘗試使用StreamReader,甚至刪除_lines.Add(line);行,我收到OutOfMemoryException。所以我不清楚你的流媒體是什麼意思。 – Behnam

+0

也許「行」終結符不是它應該是什麼?如果行沒有被\ r AND \ n終止,那麼內部函數可能仍然會將整個文件讀入內存中,對嗎? – igrimpe