簡體   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