2011-11-10 73 views
2

我有一个CSV文件。每一行是由相同的格式例如/搜索1GB 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万条记录。我刚刚尝试在调试中装载4GB内存的Dual Core Win 32bit笔记本电脑上加载它,并且它投掷了一个OutOfMemoryException

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

a)即使我坚持使用这种方法,并使用16GB内存和Windows 64位将有一个字典中的许多项目是好的?

b)您能否提供一些代码/链接的方式来搜索一个CSV迅速文件,如果你不使用词典认为这是一个很好的计划

UPDATE:虽然我已经接受一个答案,我只是想知道什么人的想法是使用FileStream进行查找然后提取数据。

+6

没有答案,只是一个建议:使用数据库,而不是一个CSV文件!如果你需要单一的数据库文件,SQLite是你的唯一。 – Marco

+0

将1GB数据存入内存绝对不是一个明智的选择。您可能不希望程序耗尽所有可用RAM。改用DBMS。 – Raptor

+0

@Marco你是说创建的数据库文件是一个文件?如果是这样,我假设我可以通过创建一个新的DB文件并删除任何旧文件来将CSV文件导入到数据库中? – Jon

回答

4

如果您打算搜索这么多记录,我会建议将文件批量插入到像SQL Server这样的DBMS中,并将相应的字段索引作为您的条件,然后使用SQL查询来检查有记录。

+0

通常我会同意,但是这个程序要发给没有IT知识的客户,并且将大量数据导入到数据库中需要管理我的感受 – Jon

+0

然后尝试使用简单的DBMS如MS Access。即使这可以帮助很大。 – Maheep

+0

但是系统应该将它载入DMBS本身......作为读取文件的第一部分。问题可能会创造一个最佳的结构。 如果你可以使用一些像SQLite这样的小型lightwieght数据库,这可能是最简单的 – Holger

0

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

+0

糟糕,刚才意识到我重复了Ioannis的回答......那么一定是个好主意。 – Simon

0

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

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

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

c)你可以使用像Lucene

d更高效的物理存储选项),你可以使用更高效的内存/缓存选项像Redis

0

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

+0

你能演示一个例子吗? – Jon

+0

好吧,如果你有1 GB的数据文件将它分为10个文件100毫克,然后当用户serachs运行创建10线程runasearch命令在每个文件中的第一个保证,你可以停止整个搜索,并停止它 – DeveloperX

+0

对不起,我的意思是代码明智的 – Jon

0

由于程序使用的其他StringDictionary条目,你仍然理想的需要将结果存储在内存中 - 你并不真正想要查询DB 1000的时间。 (这可能取决于您的程序是否位于数据库服务器上)!

我会研究你的结构的StringDictionary的内存使用情况,看看你的理论上的最大值是什么,看看你是否可以在功能需求的一个警告覆盖这个。否则,寻找更有效的存储方式 - 例如,将结果输出到XML文件比访问数据库更快。

+0

不完全理解你的答案,但如果我发现文件/字典和输入数据之间的匹配,我正在写一个UniqueID,通过/失败字符串到一个新文件 – Jon

+0

你已经声明“该字典在程序中的其他地方使用“所以我认为这就是为什么你想保存在内存中?如果有很多访问这个中间字典,你不希望这些访问跨越可能很慢的数据库链接。 – Paul

+0

好点。它在我的比较中只能访问3次 – Jon

0
  • 忘记MS访问。真。
  • 尝试sqlite,它将超过足够的几百万行
  • 如果你不能索引你的数据,那么不要使用数据库,使用外部工具,如egrep与适当的正则表达式来搜索特定领域。它会更快。