Skip to main content
 首页 » 编程设计

c#之分块读取csv文件进行处理

2024年12月31日27yxwkf

我有一个 .csv 文件,其中包含 100 000 条记录,其中包含五列。我正在逐行阅读并将其存储在远程数据库中。

以前,我遵循以性能为导向的方法。我正在逐行读取 .csv 文件,在同一个事务中,我正在打开与数据库的连接并关闭它。这需要严重的性能开销。 仅仅写 10 000 行,就需要一个小时。

using (FileStream reader = File.OpenRead(@"C:\Data.csv"))  
            using (TextFieldParser parser = new TextFieldParser(reader)) 
            { 
                parser.TrimWhiteSpace = true; // if you want 
                parser.Delimiters = new[] { " " }; 
                parser.HasFieldsEnclosedInQuotes = true; 
 
                while (!parser.EndOfData) 
                { 
                    //Open a connection to a database  
                    //Write the data from the .csv file line by line 
                    //Close the connection 
                 } 
             } 

现在我改变了方法。出于测试目的,我获取了一个包含 10 000 行的 .csv 文件,在读取了所有 10 000 行之后,我正在建立一个与数据库的连接并将其写入那里。

现在,唯一的问题是: 我想读取前 10 000 行并写入,类似地读取接下来的 10 000 行并写入,

using (FileStream reader = File.OpenRead(@"C:\Data.csv"))  
                using (TextFieldParser parser = new TextFieldParser(reader)) 

但是上面两行会读取整个文件。我不想完整地阅读它。 有什么方法可以逐 block 读取 .csv 文件,每 block 10 000 行?

请您参考如下方法:

试试下面的代码,它从 csv 中逐 block 读取数据

 IEnumerable<DataTable> GetFileData(string sourceFileFullName) 
    {             
 
        int chunkRowCount = 0; 
 
        using (var sr = new StreamReader(sourceFileFullName)) 
        { 
            string line = null; 
            //Read and display lines from the file until the end of the file is reached.                 
            while ((line = sr.ReadLine()) != null) 
            {                                                   
               chunkRowCount++; 
               var chunkDataTable = ; ////Code for filling datatable or whatever    
 
                if (chunkRowCount == 10000) 
                { 
                    chunkRowCount = 0; 
                    yield return chunkDataTable; 
                    chunkDataTable = null; 
                } 
            } 
        } 
        //return last set of data which less then chunk size 
        if (null != chunkDataTable)                            
            yield return chunkDataTable;             
    }