2012-07-05 59 views
2

到文件我一點都不好當涉及到數據寫入到文件的大塊。我有一個模擬結構像這樣需要一個快速的方式來寫大數據塊用C

typedef struct 
{ 
    int age; 
    float height; 
    float weight; 
    int friends [ 250000 ]; 
} Person; 

而且我可以有多達250,000人,每個有250000個朋友(一個集團)。顯然這是很多數據。如果我想保存每個結構,以便稍後加載它們,那麼C中最有效的方法是什麼?以下是我迄今爲止認爲

  1. 我不想創造了巨大的串25萬組數據,然後做單write,因爲這將使用大量的內存
  2. 我也不要由於這樣做可能會很慢,因此不想創建250,000個不同的文件。
  3. 基於索引追加文件(即人1,然後是人2 ...),但這可能也很慢。
  4. 保存數據爲二進制(這是更有效?)

編輯我正在尋找有效的方法來使用fwrite(),即無論是更快地收集所有數據,並寫入單個文件,還是創建多個文件,避免收集所有數據的開銷。

+1

你試過'fwrite'嗎? – cnicutar 2012-07-05 17:24:39

+0

@cnicutar我將編輯這個問題,以表明我正在尋找更有效的方式來使用fwrite – puk 2012-07-05 17:26:15

+1

爲什麼不使用某種數據庫? – mlibby 2012-07-05 17:26:18

回答

1

你也可以遍歷的人,只是存儲的年齡,身高和體重成員(3個fwrites),然後FRIEND_COUNT,然後遍歷所有的朋友和他們寫一個接一個。所有這些與fwrite。您不需要關心優化I/O,因爲C庫會爲您緩衝並在需要時執行大量「寫入」操作。

+0

因此,如果我遍歷所有人,並進行了這些'fwrite'調用,C庫不會立即寫入它們,而是將它們緩存以備後用?這聽起來不像C. – puk 2012-07-05 17:35:22

+1

相信我,這是真的.. =)這是使用低級函數(fwrite和write)的f函數之間的主要區別之一。如果你喜歡,你甚至可以用setvbuf設置緩衝區大小。如果您使用的是Linux,我建議在可執行文件上使用「strace」來查看正在執行的操作,您會看到一個很大的寫入(不是很多小寫操作)。 – niqueco 2012-07-05 17:39:52

+0

它會。請參閱setvbuf(3)函數。然而,fwrites不會像它們那樣優化,而且你仍然會自己承擔fwrite調用的開銷。 「儘可能少的寫作,儘可能接近MTU或FS塊的倍數」是我個人的經驗法則;因人而異。 – LSerni 2012-07-05 17:42:18

0

我認爲你正試圖[局部]重塑一個RDBMS(數據庫)。重新創建通常是一個糟糕的主意。考慮將您的數據存儲在免費的數據庫系統(例如Postgres)中。它還有其他的好處 - 你可以在沒有編寫C代碼的情況下查詢你的數據。
如果數據庫聽起來像是過度殺毒,可以使用更簡單的基於文件的數據庫存儲庫,例如BerkleyDB或SQLite。

+0

這會解決我有大量數據的問題嗎?例如,我可以傳遞一組「人員[100000000000]」並讓它處理它嗎? – puk 2012-07-05 17:31:28

+0

如果這是Python,我只需要'marshal.dump(persons)'其中'persons'是所有Person對象(結構體)的列表 – puk 2012-07-05 17:32:16

+0

@puk您可以添加記錄將一個人與另一個人綁定在一個名爲「 friendof」。所以你會有一張名爲「人」的表格和一張名爲「friendof」的表格,對於每一對朋友來說,該表格中都會有一個條目。這意味着你不必擔心知道一個人實際上有多少個朋友,它會爲你分配足夠的空間。你將能夠編寫SQL查詢來詢問朋友的朋友列表。 – 2012-07-05 19:04:46

0

我不是很清楚你的結構。

你有一個Person結構數組,和朋友[]包含其他人數組的索引?

最好的辦法將是一個人與他的朋友們區別開來。

這樣你就有了一個固定大小的人,可以將所有人存儲在一個文件中,並快速讀回人員12345的數據 - 它位於文件開頭的filepos 12345 * sizeof(Person)處。

朋友陣列可以通過

int *Friends[MAXFRIENDS] 

數組保存在內存中 - 你需要MAXFRIENDS *的sizeof(INT *)更多的內存字節爲250.000朋友們應該對64位2兆字節系統。小變化。每個指針都包含該人的friend []數組。

然後,Person的朋友進入一個名爲/ dd/cc/aabbccdd的目錄中的文件,其中aabbccdd由sprintf(「%08x」,PersonIndex)獲得。使用dd/cc會導致樹更平衡一些。要編寫朋友文件,只需指向Friends [PersonIndex]並根據需要編寫儘可能多的朋友索引(我會將FriendsNumber存儲在Person結構中)。

0

我想看看像HDF5這樣的庫,這樣你不僅可以在本機上讀取文件,而且還可以將文件提供給其他人,併爲您處理平臺可移植性問題。

相關問題