C#とオブジェクト指向プログラミングの新機能です。私はテキストファイルを解析するアプリケーションを持っています。C#エラー:OutOfMemoryException - 大きなテキストファイルを読み込んで辞書から置換する
アプリケーションの目的は、提供されたテキストファイルの内容を読み取り、一致する値を置き換えることです。
約800 MBから1.2 GBのファイルが入力として提供されると、アプリケーションはSystem.OutofMemoryExceptionエラーでクラッシュします。
調査中、ターゲットプラットフォームをx64に変更することをお勧めするいくつかの回答が出ました。
ターゲットプラットフォームを変更した後も同じ問題が発生します。続き
はコードです:
// Reading the text file
var _data = string.Empty;
using (StreamReader sr = new StreamReader(logF))
{
_data = sr.ReadToEnd();
sr.Dispose();
sr.Close();
}
foreach (var replacement in replacements)
{
_data = _data.Replace(replacement.Key, replacement.Value);
}
//Writing The text File
using (StreamWriter sw = new StreamWriter(logF))
{
sw.WriteLine(_data);
sw.Dispose();
sw.Close();
}
エラーポイント
_data = sr.ReadToEnd();
代替品への辞書です。キーには元の単語が含まれ、値には置換する単語が含まれます。
Key要素は、KeyValuePairのValue要素で置き換えられます。
ファイルが読み込まれ、置き換えられ、書き込まれるというアプローチが続いています。
文字列の代わりにStringBuilderを使ってみましたが、アプリケーションがクラッシュしました。
ファイルを1行ずつ読み込み、置き換えて書き換えることでこれを克服できますか?同じことをする効率的かつ迅速な方法は何でしょうか。
アップデート:システムメモリは8 GBで、パフォーマンスを監視すると最大100%のメモリ使用量になります。
@Tim Schmelterの回答がうまくいきます。
ただし、メモリ使用率が90%を超えます。次のコードが原因である可能性があります。
String[] arrayofLine = File.ReadAllLines(logF);
// Generating Replacement Information
Dictionary<int, string> _replacementInfo = new Dictionary<int, string>();
for (int i = 0; i < arrayofLine.Length; i++)
{
foreach (var replacement in replacements.Keys)
{
if (arrayofLine[i].Contains(replacement))
{
arrayofLine[i] = arrayofLine[i].Replace(replacement, masking[replacement]);
if (_replacementInfo.ContainsKey(i + 1))
{
_replacementInfo[i + 1] = _replacementInfo[i + 1] + "|" + replacement;
}
else
{
_replacementInfo.Add(i + 1, replacement);
}
}
}
}
//Creating Replacement Information
StringBuilder sb = new StringBuilder();
foreach (var Replacement in _replacementInfo)
{
foreach (var replacement in Replacement.Value.Split('|'))
{
sb.AppendLine(string.Format("Line {0}: {1} ---> \t\t{2}", Replacement.Key, replacement, masking[replacement]));
}
}
// Writing the replacement information
if (sb.Length!=0)
{
using (StreamWriter swh = new StreamWriter(logF_Rep.txt))
{
swh.WriteLine(sb.ToString());
swh.Dispose();
swh.Close();
}
}
sb.Clear();
置き換えられた行番号が見つかりました。データをメモリに複数回ロードするのを避けるため、これをTimのコードを使ってキャプチャすることができます。
投稿を更新して、ログファイルの最初の数行を含めてください。あなたのマシンにはどれくらいのRAMがありますか? – mjwills
それで、行ごとにそれを読んでみませんか? –
行ごとに読み込み、今はファイルサイズがマシンメモリより大きい場合、ファイルデータ全体をメモリに持ち込みます。 –