2011-06-24 92 views
5

我有4GB +文本文件(csv格式),我想在c#中使用linq处理此文件。在C中处理大文本文件#

我加载csv后运行复杂的linq查询并转换为类?

但文件大小是4GB,但应用程序内存的文件大小是双倍大小。

我该如何处理(linq和新结果)大文件?

感谢

+0

什么五:可能

from record in GetRecords("myFile.csv",new []{"Foo","Bar"},new[]{","}) where record.Foo == "Baz" select new {MyRealBar = int.Parse(record.Bar) 

项目的CSV到克莱对象序列的方法可以像创建.NET的使用 –

+0

@Rune FS我正在使用.net 4.0 – oguzh4n

回答

11

不必加载整个文件到内存中,你可以读取和处理文件中的行由行。

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照顾数据检索和内存管理。

+1

如果所有文本如果在没有回车的单行中,那么怎么办? – Burimi

+1

@Cody - 我认为csv文件不是单行文件。 –

+2

然后,您将整行处理为字节流,而不是一行行。 –

1

我觉得这是一个很好的方式... CSV

+0

[链接](http://i51.tinypic.com/5dphtg.png)问题是这样的 读字节500MB但内存2GB – oguzh4n

1

如果您使用的是.NET 4.0中,您可以使用Clay,然后写一个返回行一个IEnumerable线的方法,这让这样的代码下面

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; 
       } 
      } 
     } 
+0

感谢您的建议, 我试过这个解决方案,但它非常慢,并具有相同的内存问题。 – oguzh4n

+0

@ oguzh4n哦,我特意没有考虑到速度,因为你没有在你的帖子中提到过。我希望可读性(在这种情况下的呼叫网站)可以在任何一天超速。关于内存问题。如果你可以更精确地说明他们可以修复的问题。这并不需要一次保存多于一行的文本文件和一个粘土对象(以及一点点),所以上面的草稿有哪些内存问题,可以修复它们 –