2011-02-01 59 views
10

我必須在C++中讀取大文本文件(> 10 GB)。這是一個帶有可變長度行的csv文件。當我嘗試使用ifstream逐行閱讀時,它可以工作,但需要很長時間,我想這是因爲每當我讀取一行到磁盤並讀取時,都會導致它很慢。在C++中高效地讀取大文本文件

是否有讀取bufferes的方法,例如一次讀取250 MB(使用ifstream的讀取方法),然後從此緩衝區中獲取行,我發現很多問題與解決方案(如緩衝區可能有不完整的行等) ..

是否有一個解決方案在C++中處理所有這些情況等等。是否有任何開源庫可以做到這一點,例如boost等?

注:我會想可以避免C麥粒腫FILE *指針等

+1

標準庫已經使用緩衝區。這需要很長時間,因爲文件很大。也許你正在做別的事情。發佈您使用的代碼,我們可以對此發表評論。 – 2011-02-01 06:21:37

回答

7

嘗試使用Windows的內存映射文件的功能。這些調用被緩衝,並且您可以像處理文件一樣處理文件。 memory mapped files

+0

unix總是對此有mmap()... – vrdhn 2011-02-01 06:08:52

3

IOstreams已經使用了很多緩衝區(雖然通常只有幾千字節,而不是幾百兆字節)。你可以使用pubsetbuf來讓它使用更大的緩衝區,但我不希望有任何巨大的收益。 IOstream中的大部分開銷來自其他領域(如使用虛擬功能),而不是缺乏緩衝。

如果你在Windows上運行此,你也許可以通過編寫自己的流緩衝區,並讓它直接調用CreateFile,通過(例如)FILE_FLAG_SEQUENTIAL_SCANFILE_FLAG_NO_BUFFERING獲得一點點。在這種情況下,這些可能會大大有助於您的表現。

3

如果你想要真正的速度,那麼你將不得不停止讀取std :: string的行,並開始使用char* s到緩衝區。無論您使用ifstream::read()還是使用內存映射文件讀取緩衝區都不那麼重要,儘管read()具有的缺點是您可能在緩衝區中有N個完整行和一個不完整行,並且需要識別該行(可以通過掃描'\ n'的緩衝區的其餘部分 - 可能通過在緩衝區之後放置NUL並使用strchr)。您還需要將部分行復制到緩衝區的起始處,從文件中讀取下一個區塊,以便從該處繼續,並更改讀取的最大字符數,使其不會溢出緩衝區。如果你對FILE *感到緊張,我希望你對const char *感到滿意。...

正如你提出這個出於性能原因,我希望你已經通過配置來確保它不是你的CSV字段提取等,這是真正的瓶頸。

相關問題