C# 如何一次读取一行csv文件,并在运行时替换/编辑某些行?
我有一个60GB的csv文件,我需要做一些修改。客户希望对文件数据进行一些更改,但我不想重新生成该文件中的数据,因为这需要4天的时间C# 如何一次读取一行csv文件,并在运行时替换/编辑某些行?,c#,.net,parsing,csv,C#,.net,Parsing,Csv,我有一个60GB的csv文件,我需要做一些修改。客户希望对文件数据进行一些更改,但我不想重新生成该文件中的数据,因为这需要4天的时间 如何逐行读取文件(而不是将其全部加载到内存中!),并在执行过程中对这些行进行编辑,替换某些值等?过程如下: 打开一个StreamWriter到一个临时文件 打开目标文件的StreamReader 对于每一行: 根据分隔符将文本拆分为列 检查要替换的值的列,然后替换它们 使用分隔符将列值重新连接在一起 将该行写入临时文件 完成后,删除目标文件,并将临时文件移动到目
如何逐行读取文件(而不是将其全部加载到内存中!),并在执行过程中对这些行进行编辑,替换某些值等?过程如下:
StreamWriter
到一个临时文件StreamReader
仅使用
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);
内存映射文件是.NET Framework 4中的一项新功能,可用于编辑大型文件。 读这里
或者谷歌内存映射文件只需使用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 Map reduce…只有当修改的行的长度不超过原始行的长度时,您才能进行修改,而不仅仅是写入新文件?所以:1。阅读2。修改3.写入以复制。这是你不想做的事情,还是你只是在寻找一种“优雅”的方式来做到这一点?嗯…空间是一个考虑因素…那将占用我120 GB的硬盘…@Karthikeyanarumgam:什么?这只是一个一次性的csv文件,在hadoop实例中我不需要它!我喜欢!我去看看。谢谢。这绝对是最简单最直接的方法。有一件事,我没有想到尺寸。最终的
文件.Move
可能会非常慢。因此,您可以在与源文件相同的文件夹中创建临时文件,然后删除源文件并重命名临时文件(而不是使用GetTempFileName
和file.Move
)。这就是我最后所做的。这是快速和伟大的。谢谢