如何读取庞大的CSV文件,拥有2900万行使用.NET数据(How to read huge CSV

2019-09-26 06:44发布

我有一个巨大.csv文件,具体一.TAB拥有2900万行,文件大小文件的大小约为600 MB。 我需要读入这个IEnumerable集合。

我曾尝试CsvHelperGenericParser ,以及其他一些解决方案,但始终结束了因内存不足异常

请建议的方式来做到这一点

我努力了

var deliveryPoints = new List<Point>();

using (TextReader csvreader1 = File.OpenText(@"C:\testfile\Prod\PCDP1705.TAB")) //StreamReader csvreader1 = new StreamReader(@"C:\testfile\Prod\PCDP1705.TAB"))
using (var csvR1 = new CsvReader(csvreader1, csvconfig))
{
     csvR1.Configuration.RegisterClassMap<DeliveryMap>();
     deliveryPoints = csvR1.GetRecords<Point>().ToList();
}

using (GenericParser parser = new GenericParser())
{
     parser.SetDataSource(@"C:\testfile\Prod\PCDP1705.TAB");

     parser.ColumnDelimiter = '\t';
     parser.FirstRowHasHeader = false;
     //parser.SkipStartingDataRows = 10;
     //parser.MaxBufferSize = 4096;
     //parser.MaxRows = 500;
     parser.TextQualifier = '\"';

     while (parser.Read())
     {
         var address = new Point();
         address.PostCodeID = int.Parse(parser[0]);
         address.DPS = parser[1];
         address.OrganisationFlag = parser[2];
         deliveryPoints.Add(address);
     }
}

var deliveryPoints = new List<Point>();
csvreader = new StreamReader(@"C:\testfile\Prod\PCDP1705.TAB");
csv = new CsvReader(csvreader, csvconfig);

while (csv.Read())
{
     var address = new Point();
     address.PostCodeID = int.Parse(csv.GetField(0));
     address.DPS = csv.GetField(1);                
     deliveryPoints.Add(address);
}

Answer 1:

无需使用第三方软件。 使用网络库的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            StreamReader csvreader = new StreamReader(@"C:\testfile\Prod\PCDP1705.TAB");
            string inputLine = "";
            while ((inputLine = csvreader.ReadLine()) != null)
            {
                var address = new Point();
                string[] csvArray = inputLine.Split(new char[] { ',' });
                address.postCodeID = int.Parse(csvArray[0]);
                address.DPS = csvArray[1];
                Point.deliveryPoints.Add(address);
            }

            //add data to datatable
            DataTable dt = new DataTable();
            dt.Columns.Add("Post Code", typeof(int));
            dt.Columns.Add("DPS", typeof(string));

            foreach (Point point in Point.deliveryPoints)
            {
                dt.Rows.Add(new object[] { point.postCodeID, point.DPS });
            }

        }
    }
    public class Point
    {
        public static List<Point> deliveryPoints = new List<Point>();
        public int postCodeID { get; set; }
        public string DPS { get; set; }

    }
}


Answer 2:

它的工作通过在64位模式下运行,并通过添加<gcAllowVeryLargeObjects enabled="true" />中的app.config。



Answer 3:

问题是,你加载整个文件到内存中。 但您可以编译代码到x64,这将增加内存限制你的程序很快,但不建议,如果你能避免加载整个文件到内存中。

请注意,调用ToList()强制CsvReader到整个文件加载到内存中一次:

csvR1.GetRecords<Point>().ToList();

但是,这将加载在同一时间只有一行:

foreach(var record in csvR1.GetRecords<Point>())
{
    //do whatever with the single record
}

这样,您就可以处理无限大小的文件



文章来源: How to read huge CSV file with 29 million rows of data using .net