2012-11-16 6 views
11

のうち、私は大きなTXTファイルのサイズが500メガバイト、 ファーストで読みたい、私は読むビッグTXTファイル、メモリ例外

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

を使用しますが、それはメモリ例外の外に投げ、その後、私は行ずつ読みしてみましたしかし、再び約1.5万行を読んだ後には、メモリ例外

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に」の例外が私のマシンがそうラム8GBの持つ強力なマシンである

がmscorlib.dllで発生したが、ユーザーコードで処理されなかった

を受け私のマシンの問題であってはなりません。

p.s:このファイルをNotePadd ++で開こうとしましたが、「開くには大きすぎます」というメッセージが表示されました。

+2

質問は何ですか?あなたは物事を記述しているだけです。 –

+1

コレクションにすべてのものを格納するのは何ですか? – CyberDude

+0

@AlvinWongの問題は、私がoutofMemory Exceptionを受け取った理由です。私はそれをどのように解決できますか? – Behnam

答えて

30

IEnumerable<string>を返し、一度にすべての行をメモリにロードしないでください。File.ReadLinesを使用してください。

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(File.ReadLines(_filePath)のvar行){}のコンソールアプリケーションを作成しましたが、もう一度例外を作成します。 – Behnam

2

例外の原因は、コレクションが増加しているように見えますが、大きなファイルを読み込んでいないようです。あなたはラインと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<>メソッドを使用すると、アプリケーションのさまざまな領域にビジネスプロセスを積み重ね、処理を延期できます。 500が8よりも大きいとRAM 8GBので


「強力な」マシンは、メモリ内の500ギガバイトのファイルを保存できるようにするつもりはない(プラスあなたは、オペレーティングシステムとして8を得ることはありませんいくつかを保持している、あなたは.Netのすべてのメモリを割り当てることはできません、32ビットは2GBの制限を持って、ファイルを開き、行を格納するデータを2回保持する、オブジェクトサイズのオーバーヘッドがあります....)

メモリにすべてをロードして処理することはできません。処理の過程でファイルをストリーミングする必要があります。

+0

答えがありがたいですが、500MBではなく500MBです。 – Behnam

+0

私の2番目のアプローチでは、StreamReaderを使用しようとしましたが、_lines.Add(行)も削除しました。私はOutOfMemoryExceptionを受け取りました。私はストリーミングで何を意味するのかをはっきりと理解していません。 – Behnam

+0

「回線」ターミネータは、それが必要なものではないかもしれませんか?行が\ rで終わっていない場合、内部関数はおそらく完全なファイルをメモリに読み込みますが、そうではありませんか? – igrimpe