我有一个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<char>>
通过打开文件,读取每一行,从行中获取元素并将其添加到字典来填充它,然后关闭文件。
字典在程序的其他地方使用,它接受输入数据到程序中,然后在字典中找到键,并使用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<char>(compareElements));
}
s.Close();
我刚刚被告知CSV文件现在为800mb,其中有大约800万条记录。我刚刚尝试在我的双核Win 32位笔记本电脑上加载4GB RAM进行调试,并抛出一个OutOfMemoryException
。
我现在认为不将文件加载到内存中是最好的选择,但需要找到一种快速搜索文件的方法,以查看输入数据是否具有等于element[27]
的匹配项,然后采取该CSV中的前24个元素,并将其与输入数据进行比较。
a)即使我坚持使用这种方法并且使用16GB内存并且Windows 64bit会使字典中的许多项目都可以吗?
b)如果您不认为使用字典是一个好计划,您能否提供一些快速搜索CSV文件的代码/链接
更新:虽然我已经接受了答案,但我只是想知道人们对使用FileStream进行查找然后提取数据的想法。
答案 0 :(得分:4)
如果您打算搜索这么多记录,我建议将文件批量插入到DBMS之类的DBMS中,并为您的标准字段提供适当的索引,然后使用SQL查询检查是否存在记录。
答案 1 :(得分:0)
我们在导入包含需要聚合的数据的大型csv文件时遇到了类似的问题。最后,我们对SQL Server表进行了批量插入,并使用SQL来执行聚合。最后它很快(端到端几分钟)。
答案 2 :(得分:0)
您可以使用多种选项,但是,我同意将此数据加载到内存中并不是最佳选择。
a)您可以将数据加载到关系数据库中,尽管这对于此类数据可能过度。
b)您可以使用像RavenDB这样的NoSQL解决方案。我认为这对你来说可能是一个不错的选择。
c)您可以使用更有效的物理存储选项,例如Lucene
d)您可以使用更有效的内存/缓存选项,例如Redis。
答案 3 :(得分:0)
解决方案可以将文件分解为一些较小的文件,并在每个文件中进行并行搜索 搜索顺序将小于或等于n(读取整个文件)
答案 4 :(得分:0)
由于你的程序的其余部分使用StringDictionary条目,你仍然理想地需要将结果存储在内存中 - 你真的不想要查询DB 1000次。 (这可能取决于您的程序是否存在于数据库服务器上)!
我会查看StringDictionary对你的结构的内存使用情况,看看你的理论最大值是多少,看看你是否可以在功能要求的警告中介绍它。否则,寻找更有效的存储方式 - 例如,将结果流式传输到XML文件比访问数据库更快。
答案 5 :(得分:0)