2016-04-08 12 views
0

私は大規模なSQLスクリプト(約70MB)を持っており、すべてをメモリに読み込んだ後にGO文を分割する必要があります。File.ReadAllText OutOfMemoryException

私は次のことをやってますが、OutOfMemoryExceptionを取得しています:

var script = File.ReadAllText(scriptFile); 
var scriptName = Path.GetFileName(scriptFile); 
var commands = Regex.Split(script, "^GO\r\n", RegexOptions.Multiline | RegexOptions.IgnoreCase); 

その後、commands内の各スクリプトフラグメントのために、私はExecuteNonQueryを呼びます。この大きなスクリプトファイルをロードしようとするまで、これはすべて正常に動作します。

このテキストファイルをより効率的に解析するための提案はありますか?

+1

これを行単位で読み込んでリストに追加するだけで、 "GO"を押すと、現在のバッチを処理してから次の行に移動する必要があります。 –

+0

単純にファイル全体を読み込むのではなく、[this](http://weblogs.asp.net/jongalloway/Handling-_2200_GO_2200_-Separators-in-SQL-Scripts-_2D00_-the-easyway)を読むことができます。すべてのあなたの記憶を使い切ります。 – juharr

+0

@juharr私は昨日それを実際に読んだ。 –

答えて

3

は、一度に1行を読んStringBuilderにそれらをバッファリングし、それが「ゴー」の行を見たときに、バッファが得られます。この

public static IEnumerable<string> SplitScriptOnGo(string scriptPath) 
{ 
    var buffer = new StringBuilder(); 
    foreach (var line in File.ReadLines(scriptPath)) 
    { 
     if (line == "GO") 
     { 
      yield return buffer.ToString(); 
      buffer.Clear(); 
     } 
     else 
     { 
      buffer.AppendLine(line); 
     } 
    } 
} 

のようなものを試してみてください。 ToListを実行しない限り、結果全体を反復処理し、スクリプト全体をメモリに読み込まずに各SQL文を実行することができます。

0

ReadAllText()またはSplit()で失敗しますか?

システムの仕様がわかりませんが、メモリ不足の疑いがあります。スプリット()で失敗し、分割内の何かが無限ループを引き起こしています。

おそらく、すべてを一度に読むのではなく、最初の「行く」まで読んで実行し、次に読書を続けますか?最終的にはファイル全体を処理するか、失敗するでしょう(その時点で、デバッガで読み込んだ文字列を調べることによってどのGO文が問題を引き起こしているかを知ることになります)。