我有一个* .tsv文件,其中包含3200万条记录,我需要加载它们并进行搜索操作

时间:2018-08-11 07:54:30

标签: c# .net csv filehelpers

当我加载文件时,它会抛出“ OutOfMemoryException”。如何有效加载和搜索?

我正在使用

//to load the file.
var passEngine = new FileHelper<MyClass>.ReadFile().ToList() 
var passList = passEngine.ReadFile("Files/plain_32m.tsv");

还是有其他方法可以做到?

3 个答案:

答案 0 :(得分:0)

下面的代码将数据添加到数据表中。它还假定第一行包含列的名称

a.out

答案 1 :(得分:0)

您可以考虑采用几种方法

方法1:

如果这是一次搜索操作,并且仅从大文件中选择一小套记录,则可以使用流方法以及Linq到对象来实现。有许多开源库可用于维护它。

我将向您展示一个这样的库Cinchoo ETL

using (var p = new ChoCSVReader<MyClass>("*** Your CSV File ***")
    .WithFirstLineHeader()
    )
{
    var subset = p.Where(rec => rec.ID == 100).ToArray(); //You can apply any filter
}

方法2:

将文件加载到数据库。如果您的搜索条件很复杂,并且使用索引等改进了搜索,则此方法很有用。您可以使用EF / BulkCopy / ADO.NET加载文件。对于此类大文件,最好使用BulkCopy。示例代码显示了如何使用Bcp加载文件

string connectionString = "*** DB Connection String ***";
using (var p = new ChoCSVReader<MyClass>("*** Your CSV File ***")
    .WithFirstLineHeader()
    )
{
    using (SqlBulkCopy bcp = new SqlBulkCopy(connectionString))
    {
        bcp.DestinationTableName = "** DB Table Name **";
        bcp.EnableStreaming = true;
        bcp.BatchSize = 10000;
        bcp.BulkCopyTimeout = 0;
        bcp.NotifyAfter = 10;
        bcp.SqlRowsCopied += delegate (object sender, SqlRowsCopiedEventArgs e)
        {
            Console.WriteLine(e.RowsCopied.ToString("#,##0") + " rows copied.");
        };
        bcp.WriteToServer(p.AsDataReader());
    }
}

将文件加载到数据库后,您可以进行其他操作,例如创建索引,通过EF / ADO.NET查询和过滤数据等。

希望有帮助。

答案 2 :(得分:0)

FileHelpers具有FileHelpersAsyncEngine,它使您可以逐条记录地工作,并且避免一次读取或写入所有记录。该文档为here

var engine = new FileHelperAsyncEngine<Customer>();

// Read
using(engine.BeginReadFile("Input.txt"))
{
    // The engine is IEnumerable
    foreach(Customer cust in engine)
    {
        // your code here
        Console.WriteLine(cust.Name);
    }
}


// Write     
using(engine.BeginWriteFile("TestOut.txt"))
{
    var arrayCustomers = GetSomeMoreCustomers(); // a batch at a time
    if (arrayCustomers.Count() > 0)
    { 
        foreach(Customer cust in arrayCustomers)
        {
            engine.WriteNext(cust);
        }
    }
}