2011-01-27 67 views
6

我有一個10GB的CSV文件,它本質上是一個巨大的矩形矩陣。我試圖編寫一個函數,可以儘可能有效地訪問矩陣的單個單元格,即矩陣[12345,20000]。CSV隨機存取; C#

考慮到它的大小,顯然不可能將整個矩陣加載到二維數組中,我需要以某種方式直接從文件中讀取值。

我已經使用FileStream.Seek搜索文件隨機訪問,但不幸的是由於變量四捨五入每個單元格不是固定的寬度。我不可能找到一個特定的字節,並通過某種算術來了解我在看什麼單元格。

我考慮掃描文件併爲每行的第一個字節的索引創建一個查找表。這樣,如果我想訪問矩陣[12345,20000],我會尋找行12345的開始,然後掃描行,計算逗號,直到我到達正確的單元格。

我即將嘗試這個,但有其他人有更好的想法嗎?我相信我不會是第一個嘗試處理這樣的文件的人。

乾杯

編輯:我要指出,該文件包含了非常稀疏矩陣。如果解析CSV文件速度過慢,我會考慮將該文件轉換爲更適當且更易於處理的文件格式。什麼是存儲稀疏矩陣的最佳方式?

回答

3

我已經使用Lumenworks CSV閱讀器來查看相當大的CSV文件,可能值得快速查看它能夠快速解析文件。

Lumenworks CSV

+1

我不明白這怎麼能防止尋找和加載全部內存。這只是一個連續的閱讀器。 – 2011-01-28 00:03:21

1

索引文件將是你能做到的最好。我敢打賭。未知行的大小,除了掃描文件或索引之外,沒有辦法直接跳到該行。

唯一的問題是你的索引有多大。如果它太大,可以通過僅索引每5行(例如)行,並在5行範圍內掃描來縮小它。

3

首先,你會如何引用特定的行?它是該行的索引,以便您有另一個表或其他可以幫助您知道您感興趣哪一行的表?或者是由一個id或什麼?

這些想法浮現在腦海

  • 你的方法
  • 二進制搜索。假設您有平均長度(大小/行),您可以使用二進制搜索來查找行,假定行中有一個標識符是有序的,並可以告訴您是否遇到或未命中。
  • 加載它到數據庫!順便說一句,什麼阻止你這樣做?您甚至可以使用SQL Express - 即免費 - 並且爲了避開大小限制,您可以將分片您的數據傳輸到多個數據庫。
+0

*將其加載到數據庫* ...這將創建一個索引:) – 2011-01-27 23:59:58

+0

我喜歡二分法搜索的想法。然而,正如你所說的那樣,這將要求他在每一行csv上都有一個rowid。 – 2011-01-28 00:00:53

0

我不同意你不應該加載文件到RAM中,特別是如果你使用64位操作系統。

分配一個大小爲12345x20000的矩陣不應該是一個問題:只有大約1個。雙精度9 GB。事實上,即使尺寸較大,我仍會在64位平臺下推薦此方法(請參閱「虛擬內存」)。

其次你說你的矩陣是稀疏的,因此你可以加載到RAM中,但使用稀疏表示來節省一些內存。

總之,如果你的應用程序需要很多訪問你的矩陣和性能有點重要,把它放入RAM肯定是我最喜歡的方法。

0

預處理文件,使字段固定寬度。然後,你可以輕鬆地做你的隨機閱讀。

從以前的類似情況看,您應該能夠編寫一些簡單的代碼,從本地磁盤讀取10G變量寬度文件,並在一些(〜20)文件中將10G固定寬度文件寫入本地磁盤,分鐘。如果前期投資的回報取決於您需要進行多少次隨機讀取以及要讀取的文件多久更新一次。

0

如果您創建了12345單獨的文件,並使用Lazy實例化讀取該怎麼辦。只有在需要數據時纔會讀取每個文件。如果數據完全稀疏,則可以使用IsEmpty布爾屬性創建數據結構。

您是否需要反覆訪問相同的元素,或者是否需要只讀取一次元素?