簡體   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