いくつかの変更を加える必要がある60GBのcsvファイルがあります。お客様はファイルデータの変更を望んでいますが、4日かかったため、そのファイルのデータを再生成したくありません。
ファイルを1行ずつ読み取り(すべてをメモリにロードしないでください!)、特定の値などを置き換えながら、それらの行を編集するにはどうすればよいですか?
プロセスは次のようになります。
StreamWriter
一時ファイルを開きます。StreamReader
ターゲット ファイルを開きます。ステップ 2 と 3.1 に関する注意: ファイルの構造に自信があり、それが十分に単純である場合は、説明されているように、すぐに使用できます (すぐにサンプルを含めます)。ただし、CSV ファイルには注意が必要な要素があります (区切り文字が列の値でそのまま使用されている場合の認識など)。これを自分で苦労するか、既存のソリューションを試すことができます。
StreamReader
andを使用した基本的な例StreamWriter
:
var sourcePath = @"C:\data.csv";
var delimiter = ",";
var firstLineContainsHeaders = true;
var tempPath = Path.GetTempFileName();
var lineNumber = 0;
var splitExpression = new Regex(@"(" + delimiter + @")(?=(?:[^""]|""[^""]*"")*$)");
using (var writer = new StreamWriter(tempPath))
using (var reader = new StreamReader(sourcePath))
{
string line = null;
string[] headers = null;
if (firstLineContainsHeaders)
{
line = reader.ReadLine();
lineNumber++;
if (string.IsNullOrEmpty(line)) return; // file is empty;
headers = splitExpression.Split(line).Where(s => s != delimiter).ToArray();
writer.WriteLine(line); // write the original header to the temp file.
}
while ((line = reader.ReadLine()) != null)
{
lineNumber++;
var columns = splitExpression.Split(line).Where(s => s != delimiter).ToArray();
// if there are no headers, do a simple sanity check to make sure you always have the same number of columns in a line
if (headers == null) headers = new string[columns.Length];
if (columns.Length != headers.Length) throw new InvalidOperationException(string.Format("Line {0} is missing one or more columns.", lineNumber));
// TODO: search and replace in columns
// example: replace 'v' in the first column with '\/': if (columns[0].Contains("v")) columns[0] = columns[0].Replace("v", @"\/");
writer.WriteLine(string.Join(delimiter, columns));
}
}
File.Delete(sourcePath);
File.Move(tempPath, sourcePath);
メモリ マップト ファイルは、大きなファイルの編集に使用できる .NET Framework 4 の新機能です。ここを読んでください http://msdn.microsoft.com/en-us/library/dd997372.aspx または google メモリマップされたファイル
streamreader を使用してファイルを 1 行ずつ読み取り、REGEX を使用するだけです。世界で最も素晴らしいツール。
using (var sr = new StreamReader(new FileStream(@"C:\temp\file.csv", FileMode.Open)))
{
var line = sr.ReadLine();
while (!sr.EndOfStream)
{
// do stuff
line = sr.ReadLine();
}
}