[英]Efficient way to split CSV files in c#
我正在尝试根据帐单中的电话号码将CSV文件(300MB)的大型电信帐单拆分为较小的块。
有些电话号码的帐单为20行,有些电话号码的行数超过1000行,因此它是动态的。 初次通过时,我阅读了帐单,并使用LINQ将其按电话号码分组,并为CSV文件中的每个电话号码帐单计算了帐单包含的行数。 然后插入List:split_id,开始行,结束行。 (起始行从0开始)。
下面的脚本是我用来分割较小的钞票的脚本。 但是,即使每个文件的大小降至100KB以下,这300MB的电话号码通常也有7500多个,这需要花费永远的时间来处理拆分账单。
static void FileSplitWriter(List<SplitFile> pList, string info)
{
pList.ForEach(delegate(SplitFile per)
{
int startingLine = per.startingLine;
int endingLine = per.endingLine;
string[] fileContents = File.ReadAllLines(info);
var query = fileContents.Skip(startingLine - 1).Take(endingLine - (startingLine - 1));
string directoryPath = Path.GetDirectoryName(info);
string filenameok = Path.GetFileNameWithoutExtension(info);
StreamWriter ffs = new StreamWriter(directoryPath + "\\" + filenameok + "_split" + per.id + ".csv");
foreach (string line in query)
{
ffs.WriteLine(line);
}
ffs.Dispose();
ffs.Close();
});
}
我的问题是,这个过程是否可能更快/更有效? 以目前的速度,单独分割文件将需要3个小时左右。
它看起来像这样的代码的最没有效率的部分是,你正在阅读的整个300MB的文件到内存中多次 。 您只需要阅读一次...
注意:如果使用的是.NET 4.0,则可以通过使用File.ReadLines()
(而不是ReadAllLines)来提高内存效率。
我建议您使用现有的许多快速CSV解析库之一。
在代码项目和其他地方有几篇文章以及filehelpers 。
尝试将文件的读取移到循环外:
static void FileSplitWriter(List<SplitFile> pList, string info) {
string[] fileContents = File.ReadAllLines(info);
string directoryPath = Path.GetDirectoryName(info);
string filenameok = Path.GetFileNameWithoutExtension(info);
pList.ForEach(delegate(SplitFile per) {
int startingLine = per.startingLine;
int endingLine = per.endingLine;
var query = fileContents.Skip(startingLine - 1).Take(endingLine - (startingLine - 1));
StreamWriter ffs = new StreamWriter(directoryPath + "\\" + filenameok + "_split" + per.id + ".csv");
foreach (string line in query) {
ffs.WriteLine(line);
}
ffs.Close();
ffs.Dispose();
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.