C# 用C语言处理大型文本文件#
我有4GB+文本文件(csv格式),我想用c#中的linq处理这个文件 我在加载csv并转换为类之后运行复杂的linq查询 但文件大小是4gb,尽管应用程序内存是文件大小的两倍 如何处理(linq和新结果)大文件C# 用C语言处理大型文本文件#,c#,.net,string,c#-4.0,.net-4.0,C#,.net,String,C# 4.0,.net 4.0,我有4GB+文本文件(csv格式),我想用c#中的linq处理这个文件 我在加载csv并转换为类之后运行复杂的linq查询 但文件大小是4gb,尽管应用程序内存是文件大小的两倍 如何处理(linq和新结果)大文件 谢谢您可以逐行读取和处理文件,而不是将整个文件加载到内存中 using (var streamReader = new StreamReader(fileName)) { string line; while ((line = streamReader.ReadLine
谢谢您可以逐行读取和处理文件,而不是将整个文件加载到内存中
using (var streamReader = new StreamReader(fileName))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
// analize line here
// throw it away if it does not match
}
}
[编辑]
如果您需要对文件中的数据运行复杂的查询,正确的做法是将数据加载到数据库中,让DBMS负责数据检索和内存管理。我认为这是一个好方法。。。
如果您使用的是.NET 4.0,那么您可以使用并编写一个方法,该方法返回一个IEnumerable行对一行,并使下面这样的代码成为可能
from record in GetRecords("myFile.csv",new []{"Foo","Bar"},new[]{","})
where record.Foo == "Baz"
select new {MyRealBar = int.Parse(record.Bar)
将CSV投影到粘土对象序列中的方法可以创建为:
private IEnumerable<dynamic> GetRecords(
string filePath,
IEnumerable<string> columnNames,
string[] delimiter){
if (!File.Exists(filePath))
yield break;
var columns = columnNames.ToArray();
dynamic New = new ClayFactory();
using (var streamReader = new StreamReader(filePath)){
var columnLength = columns.Length;
string line;
while ((line = streamReader.ReadLine()) != null){
var record = New.Record();
var fields = line.Split(delimiter, StringSplitOptions.None);
if(fields.Length != columnLength)
throw new InvalidOperationException(
"fields count does not match column count");
for(int i = 0;i<columnLength;i++){
record[columns[i]] = fields[i];
}
yield return record;
}
}
}
private IEnumerable GetRecords(
字符串文件路径,
IEnumerable列名称,
字符串[]分隔符){
如果(!File.Exists(filePath))
屈服断裂;
var columns=columnNames.ToArray();
动态新=新工厂();
使用(var streamReader=newstreamreader(filePath)){
var columnLength=columns.Length;
弦线;
而((line=streamReader.ReadLine())!=null){
var record=New.record();
var fields=line.Split(分隔符,StringSplitOptions.None);
如果(fields.Length!=columnLength)
抛出新的InvalidOperationException(
“字段计数与列计数不匹配”);
对于(int i=0;i如果所有文本都在一行中而没有回车符,那该怎么办?@Cody-我假设csv文件不是一行文件。然后您将整个行作为字节流而不是行流进行处理。@Cody那么这是一条记录,可能需要一次处理,因为您无法预先知道是什么字段将出现在lin查询中,或者使用了一个不寻常的记录分隔符,OP很可能会包括,因为这是一个关键的细节,我应该将所有数据加载到内存中,以便运行linq查询并创建新结果?您使用的是.NET的哪个版本?问题是这个读取字节500MB,但内存2GB感谢您的建议,我尝试了这个解决方案在上,但速度非常慢,并且有相同的内存问题。@oguzh4n哦,我谨慎地没有考虑速度,因为你在帖子中没有提到。我更喜欢可读性(在呼叫站点的例子中)任何一天都可以超速。关于内存问题。如果你能更精确地描述这些问题,它们可以被修复。一次(一点)不必保存一行以上的文本文件和一个粘土对象,所以上面草稿中的任何内存问题都可以被修复