Lee*_*Lee 6 .net c# csv streamreader
我有一个巨大的.csv文件,具体来说是一个.TAB有 2900 万行的文件,文件大小约为 600 MB。我需要把它读到一个IEnumerable集合中。
我已经尝试过CsvHelper,GenericParser和其他一些解决方案,但总是以内存不足异常告终
请建议一种方法来做到这一点
我试过了
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);
}
}
Run Code Online (Sandbox Code Playgroud)
和
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);
}
Run Code Online (Sandbox Code Playgroud)
jdw*_*eng 12
无需使用第三方软件。使用网络库方法
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
问题是您正在将整个文件加载到内存中。您可以将代码编译为 x64,这将快速增加程序的内存限制,但如果可以避免将整个文件加载到内存中,则不建议这样做。
请注意,调用 ToList() 会强制 CsvReader 一次将整个文件加载到内存中:
csvR1.GetRecords<Point>().ToList();
Run Code Online (Sandbox Code Playgroud)
但这一次只会加载一行:
foreach(var record in csvR1.GetRecords<Point>())
{
//do whatever with the single record
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以处理无限大小的文件
Lee*_*Lee -1
它通过在 x64 模式下运行并添加
<gcAllowVeryLargeObjects enabled="true" />到 app.config 中来工作。