如何处理大量数据的解析(800k记录)?

问题描述:

我有一个桌面应用程序验证某些CSV文件。 我得到这个CSV文件,我需要根据多个业务规则进行解析和验证。这些业务规则特别适用于每条记录,或者他们可以检查具有与文件中所有记录有关的范围的集成债券。该文件几乎有800k条记录。如何处理大量数据的解析(800k记录)?

这里是我如何处理目前的问题:

  1. 我上传CSV文件,每行转换为自定义对象(for循环用在这里),我最终存储在列表中。这一点通常需要3到6秒,所以我不认为这是一个问题。
  2. 我将列表传递给验证程序类,由于StructureMap将所有业务规则作为单独的类获取。
  3. 我遍历业务规则。我的第一个业务规则抛出一个异常,这样的:

的CLR一直无法从COM上下文0xa4234fc8转换为COM上下文0xa42350f0 60秒。拥有目的地上下文/公寓的线程很可能要么进行非抽水等待,要么处理非常长的运行操作而不抽取Windows消息。这种情况通常会对性能产生负面影响,甚至可能导致应用程序无法响应或内存使用量不断累积。为了避免这个问题,所有的单线程单元(STA)线程都应该使用抽取等待原语(比如CoWaitForMultipleHandles),并在长时间运行的操作中定期抽取消息。

我明白这可以隐藏,但我不想隐藏错误,我想了解我能做些什么来使代码更有效。我已经消除了代码中抛出的所有异常,并且它工作得更好。

对于每一个我跑业务规则中下面的代码记录:

var mandatoryFields = GetFieldsWithAttribute<MandaroryFieldAttribute>(package); 

foreach (var field in mandatoryFields) 
{ 
    var fieldValue = field.GetValue(package, null).ToString(); 

    if (!string.IsNullOrWhiteSpace(fieldValue)) 
     continue; 

    var errorMessage = GetErrorMessage(package.RowNumber, field.Name, 
     field.GetAttributeForPackage<CsvFieldNameAttribute>().Name); 

    if (FailedResults.Contains(errorMessage)) 
     continue; 

    FailedResults.Add(errorMessage); 
} 

因为有很多领域 - 我决定来验证使用自定义属性,使这一过程更加通用的领域。 System.Reflection在两个扩展方法中使用:GetAttributeForPackage和GetFieldsWithAttribute。

  1. 写一个总结验证的报告到文本文件。

正如我所看到的,问题在于我必须解析每条记录,对于某条规则解析某条规则的所有记录。

我没有解析大量数据的经验。任何人都可以提出如何处理这个问题的方法吗?

+0

为什么不一行一行地阅读文件,或者一束一行地阅读文件,比如说1.000行? –

+0

@RomanoZumbé,因为“业务规则...可以检查具有与文件中所有记录有关的范围的集成债券” – Evk

+1

如果将它们存储在列表中,则最多可处理N条记录。墨菲法则要求您迟早会得到一份N + 1记录的CSV文件。 SO的赔率为100%。项目“>”属性“>”生成“选项卡,取消选中”优先选择32位“复选框。你不喜欢它。 –

有几件事情,可以帮助你:

  • 既然你已经大的文件,我建议你使用Memory-mapped files 。这使程序员非常大的文件

    既然你有很多的工作记录进行验证,您可以考虑使用线程或并行编程(任务) 。这样的执行将会更快, 。

    我想你正在使用StreamReader.ReadLine来读取每个 行。

+0

其实我用File.ReadAllLines来读取整个文件,然后用for循环转换每一行。 –