搜索1GB CSV文件

我有一个CSV文件。 每一行都由相同的格式组成,例如/

I,h,q,q,3,A,5,Q,3,[,5,Q,8,c,3,N,3,E,4,F,4,g,4,I,V,9000,0000001-100,G9999999990001800000000000001,G9999999990000001100PDNELKKMMCNELRQNWJ010, , , , , , ,D,Z, 

我有一个Dictionary<string, List>

它通过打开文件,读取每一行,从行中获取元素并将其添加到字典来填充,然后关闭文件。

该字典在程序的其他地方使用,它接受输入数据到程序中,然后在字典中找到密钥并使用24个元素与输入数据进行比较。

 StreamReader s = File.OpenText(file); string lineData = null; while ((lineData = s.ReadLine()) != null) { var elements = lineData.Split(','); //Do stuff with elements var compareElements = elements.Take(24).Select(x => x[0]); FileData.Add(elements[27], new List(compareElements)); } s.Close(); 

我刚刚被告知CSV文件现在将是800mb,并且其中有大约800万条记录。 我刚刚尝试在我的双核Win 32位笔记本电脑上加载4GB RAM进行调试,它抛出了OutOfMemoryException

我现在认为不将文件加载到内存中是最好的选择,但需要找到一种快速搜索文件的方法,以查看输入数据是否具有与element[27]相等的匹配项,然后获取前24个元素在该CSV中并将其与输入数据进行比较。

a)即使我坚持使用这种方法并使用16GB内存并且Windows 64bit会让字典中的许多项目都可以吗?

b)如果您不认为使用字典是一个好的计划,您能否提供一些快速搜索CSV文件的代码/链接

更新:虽然我接受了答案,但我只是想知道人们对使用FileStream进行查找然后提取数据的想法。

如果您计划搜索这么多记录,我建议将文件批量插入到DBMS之类的DBMS中,并为您的标准字段提供适当的索引,然后使用SQL查询检查是否存在记录。

我们在导入包含需要聚合的数据的大型csv文件时遇到了类似的问题。 最后,我们对SQL Server表进行了批量插入,并使用SQL来执行聚合。 最后它很快(端到端几分钟)。

有几种选择,但是,我同意将这些数据加载到内存中并不是最好的选择。

a)您可以将数据加载到关系数据库中,尽管这对于此类数据可能过度。

b)您可以使用像RavenDB这样的NoSQL解决方案。 我认为这对你来说可能是一个不错的选择。

c)您可以使用像Lucene这样更有效的物理存储选项

d)您可以使用更有效的内存/缓存选项,如Redis 。

解决方案可以将文件分解为一些较小的文件,并在每个文件中进行并行搜索,搜索顺序将小于或等于n(读取整个文件)

由于程序的其余部分使用StringDictionary条目,您仍然需要将结果存储在内存中 – 您真的不想查询数据库1000次。 (这可能取决于您的程序是否存在于数据库服务器上)!

我将研究StringDictionary的内存使用情况,看看你的理论最大值,看看你是否可以在function要求的警告中介绍它。 否则寻找更有效的存储方式 – 例如,将结果流式传输到XML文件比访问数据库更快。

  • 忘记MS访问。 真。
  • 尝试sqlite,它将足以满足几百万行
  • 如果您无法索引数据,则不要使用数据库,使用egrep等外部实用程序和相应的正则表达式来搜索特定字段。 它会快得多。