我有一個60GB的csv文件,我需要做一些修改。客戶希望對文件數據進行一些更改,但我不想重新生成該文件中的數據,因爲需要4天才能完成。如何一次讀取一行csv文件,並隨時替換/編輯某些行?
如何逐行讀取文件(並非全部加載到內存中!),並對這些行進行編輯,替換某些值等。
我有一個60GB的csv文件,我需要做一些修改。客戶希望對文件數據進行一些更改,但我不想重新生成該文件中的數據,因爲需要4天才能完成。如何一次讀取一行csv文件,並隨時替換/編輯某些行?
如何逐行讀取文件(並非全部加載到內存中!),並對這些行進行編輯,替換某些值等。
的過程會是這樣的:
StreamWriter
到一個臨時文件。StreamReader
。有關步驟2和3.1的注意事項:如果您對文件的結構很有信心,並且它足夠簡單,那麼您可以按照描述的方式完成所有這些操作(我將在一會兒包括一個示例)。但是,CSV文件中可能需要注意的因素(例如識別分隔符何時在字段值中逐字地使用)。你可以自己完成這個嘗試,或者試試existing solution。只是用StreamReader
和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);
這絕對是簡單和最直接的方式去。 – richard
我更新它來處理分隔符的字面出現。 – HackedByChinese
有一件事,我沒有想到大小。最終的'File.Move'可能會很慢。相反,您可能只是在源文件所在的文件夾中創建臨時文件,然後刪除源文件並重命名temp(而不是使用'GetTempFileName'和'File.Move')。 – HackedByChinese
內存映射文件是可以用來編輯大型文件的.NET Framework 4的新功能。 在這裏閱讀http://msdn.microsoft.com/en-us/library/dd997372.aspx 或谷歌內存映射文件
我喜歡它!我會看看。謝謝。 – richard
只需閱讀文件,逐行,與streamreader,然後使用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();
}
}
在這種情況下
你爲什麼不嘗試使用Hadoop地圖降低.... –
您將能夠做的只有修改線將有長度不超過原線路長度 –
修改爲什麼不只是寫一個新文件?所以:1.閱讀2.修改3.寫入複製。那是你不想做的事情,還是你正在尋找一種「優雅」的方式來做到這一點? – StampedeXV