CSV随机访问; C#

时间:2011-01-27 23:45:37

标签: c# file csv random-access

我有一个10GB的CSV文件,它本质上是一个巨大的方阵。我正在尝试编写一个能够尽可能有效地访问矩阵的单个单元格的函数,即矩阵[12345,20000]。

鉴于它的大小,显然不可能将整个矩阵加载到2D数组中,我需要以某种方式直接从文件中读取值。

我已经使用FileStream.Seek查看文件随机访问,但遗憾的是由于变量舍入,每个单元格不是固定宽度。我不可能通过某种算法寻找一个特定的字节并知道我在看什么单元格。

我考虑扫描文件并为每行的第一个字节的索引创建一个查找表。这样,如果我想访问矩阵[12345,20000],我会寻找行12345的开头,然后扫描整行,计算逗号直到我到达正确的单元格。

我即将尝试这个,但还有其他人有更好的想法吗?我确信我不会是第一个试图处理这样一个文件的人。

干杯

编辑:我应该注意该文件包含一个非常稀疏的矩阵。如果解析CSV文件的速度太慢,我会考虑将文件转换为更合适,更容易处理的文件格式。存储稀疏矩阵的最佳方法是什么?

6 个答案:

答案 0 :(得分:3)

我已经将Lumenworks CSV阅读器用于相当大的CSV文件,可能需要快速查看它可以快速解析文件。

Lumenworks CSV

答案 1 :(得分:3)

首先,您想如何引用特定行?它是行的索引,以便您有另一个表或某些东西,可以帮助您知道您感兴趣的行?或者它是由id还是什么?

想到这些想法

  • 您的方法
  • 二进制搜索。假设您有平均长度(大小/行),您可以使用二进制搜索来查找行,假设订单行中有一个标识符,可以告诉您是否被击中。
  • 将其加载到数据库!顺便说一句,是什么阻止你这样做?您甚至可以使用免费的SQL Express - 并且为了达到大小限制,您可以分片您的数据到多个数据库。

答案 2 :(得分:1)

索引文件将是您可以做的最好的。我打赌。如果行的大小未知,除了扫描文件或索引之外,无法直接跳到该行。

唯一的问题是您的索引有多大。如果它太大,你可以通过仅每隔5行(例如)索引并在5行范围内扫描来缩小它。

答案 3 :(得分:0)

我不同意您不应该将文件加载到RAM中,尤其是在使用64位操作系统时。

分配大小为12345x20000的矩阵应该不是问题:双精度只有大约1.9 GB。事实上,即使尺寸更大,我仍然会在64位平台下推荐这种方法(参见“虚拟内存”)。

其次,你说你的矩阵是稀疏的,因此你可以加载到RAM中,但使用稀疏表示来节省一些内存。

总之,如果你的应用程序需要很多访问你的矩阵并且性能有点重要,那么将它放在RAM中肯定是我最喜欢的方法。

答案 4 :(得分:0)

预处理文件,使字段的宽度固定。然后你可以轻松地随意阅读。

从过去做过类似的事情,您应该能够编写一些简单的代码,从本地磁盘读取10G可变宽度文件,并在几(~20)分钟内将10G固定宽度文件写入本地磁盘。如果前期投资得到回报,取决于您需要做多少随机读取以及读取文件的频率发生变化。

答案 5 :(得分:0)

如果您创建了使用Lazy实例化读取的12345单独文件,该怎么办?只有在需要数据时才会读取每个文件。如果数据完全稀疏,您可以使用IsEmpty bool属性创建数据结构。

您是否需要反复访问相同的元素,还是只需要读取一次元素?