繁体   English   中英

在C#中分割CSV文件的有效方法

[英]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的文件到内存中多次 您只需要阅读一次...

  1. 将文件读入一些可枚举的数据结构。
  2. 按电话号码分组。
  3. 遍历每个组并将每个组写入文件。

注意:如果使用的是.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM