繁体   English   中英

C#:CSV文件中特定列的最快方法

[英]C# : Fastest way for specific columns in CSV Files

我有一个非常大的CSV文件(数百万条记录)
我开发了一种智能搜索算法,可以在文件中定位特定的行范围,以避免解析整个文件。

现在,我面临一个棘手的问题:我只对特定列的内容感兴趣。
有没有一种聪明的方法来避免在200MB的文件中逐行循环,而仅检索特定列的内容?

您是说要从特定列的每一行获取每个值?

您可能必须走遍每一行。

这个C#CSV阅读库非常快,因此您可以使用它:

Sebastien Lorien编写的LumenWorks.Framework.IO.Csv

我会按照codeulike的建议使用现有的库,出于一个很好的理由,为什么要阅读本文:

停止滚动自己的CSV解析器!

除非所有 CSV字段的宽度都固定(除非为空,否则即使周围为n字节,分隔符之间仍然还有n个字节的空白)。

如是

然后,每一行又具有固定的长度,因此您可以直接跳到该列的第一个值,并且,一旦您阅读了它,就可以立即前进到同一字段的下一行的值,而不必阅读任何中间值。

我认为这很简单-但此刻(和午餐时)我正在忙碌着,所以无论如何我都要完成它:)

为此,我们首先要知道每一行的字符长度 (根据Unicode,UTF8等调整字节):

row_len = sum(widths[0..n-1]) + n-1 + row_sep_length

其中n是每一行的总列数-这是整个文件的常数。 我们添加了一个额外的n-1来解决列值之间的分隔符。

row_sep_length是两行之间的分隔符的长度-通常是换行符,或者可能是[回车和换行]对。

row[r]col[i]将是距row [r]开头的offset字符,其中offset定义为:

offset = i>0 ? sum(widths[0..i-1]) + i) : 0;
//or sum of widths of all columns before col[i]
//plus one character for each separator between adjacent columns

然后, 假设您已读取整个列的值,直到下一个分隔符,则通过从列中减去列的宽度来计算下一个列值的起始字符的偏移量row[r+1]col[i]行长。 这是文件的另一个常量:

next-field-offset = row_len - widths[i];
//widths[i] is the width of the field you are actually reading.

一直- i在这个伪代码中从零开始,向量/数组的索引也是如此。

要进行读取,请首先将文件指针前移offset字符-将您带到所需的第一个值。 您读取该值(将您带到下一个分隔符),然后只需将文件指针前移next-field-offset字符即可。 如果此时达到EOF ,就完成了。

我可能会错过任何一种字符-因此,如果适用-请检查一下!

仅当您可以保证所有行的所有字段值-甚至为null-都将是相同的长度,并且分隔符始终是相同的长度,并且alll行分隔符是相同的长度时,这才起作用。 如果没有,那么这种方法将行不通。

如果不

您将必须以慢速的方式进行操作-在每一行中找到该列,然后执行您需要执行的所有操作。

如果您每次都要对列值进行大量工作,则一种优化方法是首先将所有列值拉到一个列表中(也设置一个已知的初始容量)或某个内容(一次以100,000为上限,这样的东西),然后遍历那些。

如果让每个循环都专注于一个任务,那应该比一个大循环更有效。

同样,一旦批处理了100,000个列值,就可以使用Parallel Linq分发第二个循环(而不是第一个循环,因为没有点并行读取文件)。

如果您可以对数据进行特定限制,则只有快捷方式。

例如,如果您知道文件中没有包含换行符的值,则只能逐行读取文件。 如果不知道,则必须按记录将文件记录解析为流,并且每个记录在没有值的换行符处结束。

但是,除非您知道每一行占用的字节数完全相同,否则除了逐行读取文件外,没有其他方法可以读取文件。 文件中的换行符只是另一对字符,在文本文件中找到一行的唯一方法就是读取该行之前的所有行。

如果您可以在记录中的字段上添加限制,则可以在读取记录时执行类似的快捷方式。 例如,如果您知道要插入的字段左侧的字段都是数字字段,则可以使用一种更简单的解析方法来查找该字段的开头。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM