我正在尝试将一个大型电信账单拆分为CSV文件,根据账单中的电话号码将300MB分成较小的块。
有些电话号码有20行,有些有超过1000行,所以它是动态的。在第一次通过时,我阅读账单并使用LINQ按电话号码对它们进行分组,并计算CSV文件中每个电话号码计费的账单所包含的行数。然后插入List:split_id,起始行,结束行。 (起始线从0开始)。
以下脚本是我用来拆分较小账单的。但是这300MB拥有超过7500个电话号码,即使每个文件都低于100KB,也需要永远处理拆分账单。
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个小时左右。
答案 0 :(得分:3)
看起来此代码中效率最低的部分是您将整个300MB文件读入内存多次次。你应该只需要阅读一次......
注意:如果您使用的是.NET 4.0,则可以使用File.ReadLines()
(而不是ReadAllLines)来提高内存效率。
答案 1 :(得分:2)
我建议您使用存在的许多快速CSV解析库之一。
在代码项目和其他地方发布了several个,以及filehelpers。
答案 2 :(得分:2)
尝试将文件的读取移动到循环外部:
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();
});
}