2010-04-12 14 views
3

對於這個大學項目,我正在做這些工作(我過去曾經發表過幾篇文章),這是一種社交網絡,它需要用戶交換消息的能力。首先,我設計了我的數據結構來保存鏈接列表中的所有消息,將消息大小限制爲256個字符。但是,我認爲我的導師會更喜歡將信息保存在磁盤上,並只在需要時纔讀取它們。當然,他們不會說出他們喜歡的東西,我需要做出選擇併爲我能走上最佳路線辯護。很多關於文件I/O的問題(讀/寫信息字符串)

有一點要記住,我只需要保存來自每個用戶的最新20條消息,不再需要。

現在我有一個哈希表,它將充當收件箱,這將在用戶配置文件中。該哈希表將按名稱(發送消息的用戶)編入索引。每個元素的值將是一個數據結構,其中包含具有20個元素的size_t的數組(像上面所述的20條消息)。這個想法是跟蹤磁盤文件偏移和寫入的字節。然後,當我需要閱讀消息時,我只需要使用fseek()並讀取必要的字節。

我認爲這可以很好地工作......我只能用一個文件來保存來自網絡中所有用戶的所有消息。我是在說一個文件,因爲一位同事問一位講師關於獨立保存每個用戶的消息,他回答說,這可能不是最好的方法,因爲文件系統有限制。這就是爲什麼我想要去單一文件路線。

但是,這提出了一個問題...因爲我只需要保存最新的20條消息,所以當我達到此限制時,我需要丟棄較舊的消息。

我不知道如何做到這一點...我所知道的全部是關於fread()fwrite()來讀取/寫入文件的字節。我怎麼去一個文件偏移量,並說「嘿,刪除下面的X字節」?即使我可以做到這一點,還有一個問題......低於這一點的所有偏移將完全不同,我將不得不處理所有用戶郵箱來解決問題。這將是一個痛苦...

那麼,有什麼建議來解決我的問題?你有什麼建議?

回答

2

您不能任意刪除文件中間的字節;唯一有效的方法是不用它們來重寫整個文件。不管是否這樣做是一個好主意,如果你有固定長度的字段,一個解決方案將是用最新的一個覆蓋最舊的消息;這樣,磁盤上消息的大小/位置不會改變,所以其他偏移量都不會受到影響。

編輯:如果您可以使用外部庫,那麼製作一個簡單的SQLite db可能是一個很好的解決方案。

+0

這就是我的想法......我不喜歡使用固定長度的消息。最大值是256,但如果消息是簡單的「你好,你在幹什麼?」我不想寫256個字節。我被允許使用這樣的外部庫。這將打敗目的... – 2010-04-12 00:43:29

0

你讓你的生活方式變得比你需要的更復雜。

如果您的消息是256個字符,則使用256個字符的數組來保存每條消息。

使用fwrite將其寫入磁盤,使用fread讀取,通過將字符串的第一個字符更改爲\ 0(或任何其他觸擊您的想象)並將其寫入磁盤來刪除它。

用簡單的結構(username/recno)保留消息的索引並用fseek在文件中反彈。你可以在編寫新文件時強制下一個空閒記錄(在文件的開始處開始閱讀,當你點擊\ 0時停止),或者在數組中保留空閒記錄的索引,並在寫入時獲取其中的一個一個新的(或者,如果你的數組爲空,則FSEEK到文件的末尾,寫一個完整的新紀錄。)

+0

我沒有得到你的答案的大部分,我不認爲你正確地理解了這個問題。我可以說的一件事是我不想使用256個字符的數組,我不想將消息存儲在內存中。那是我的第一個方法,那就是我想要避免的。這不僅僅是一個用戶的一條消息,而是成千上萬個用戶的20條消息(當然最多)。 – 2010-04-12 00:38:28

+0

您必須將活動消息放在某處,以便進入256個字符數組。即使消息只有10個字符長,也可以將該陣列保存爲一個256字符記錄的磁盤。然後,您可以通過重新搜索* 256來輕鬆找到它。通過一個簡單的結構跟蹤recno和sender,如果你喜歡,ram或其他磁盤文件,你可以保存一個數組。我不知道有什麼不清楚的。具有固定長度字符串和單獨索引數組的簡單隨機訪問文件。 – 2010-04-12 00:44:20

+0

就像我說的,我不喜歡/想要那樣。我不會爲每個消息保存256個字節,而應該只保存幾個字節(如果消息確實很少)。這是浪費空間。 – 2010-04-12 00:52:48

0

我想建議的完整性另一種解決方案的緣故:

字符串應該與結束一個空字節字符"hello world\0",所以您可能會讀取原始二進制數據,直到達到"\0"。 其他數據類型有固定位,小心byteorder(endian)。

也可以在每次消息之前定義的有效載荷,讓你知道它的字符串長度:

"11hello world;2hi;15my name is loco" 

因此使其能夠像對待數據字段的原始片段。