2010-08-18 152 views
4

背景:馬歇爾多的protobuf到文件

我使用谷歌的protobuf,我想讀/寫的protobuf的幾個GB使用C++整理數據文件。因爲建議將每個protobuf對象的大小保持在1MB以下,所以我認爲寫入文件的二進制流(如下所示)會起作用。每個偏移量都包含到達下一個偏移量的字節數,直到文件結束。這樣,每個protobuf可以保持在1MB以下,並且我可以將它們放在一起以符合我心中的內容。

[int32 offset] 
[protobuf blob 1] 
[int32 offset] 
[protobuf blob 2] 
... 
[eof] 

我有在Github上起作用的implemntation:

src/glob.hpp
src/glob.cpp
test/readglob.cpp
test/writeglob.cpp

但我覺得我已經寫了一些差的代碼,並希望得到一些建議如何改善它。因此,

問題:

  • 我使用reinterpret_cast<char*>讀/寫的32位整數從二進制fstream。由於我使用protobuf,所以我假設所有機器都是小端。我還斷言int確實是4個字節。 鑑於這兩個限制性假設,是否有更好的方法來讀取/寫入32位整數爲二進制fstream
  • 在從fstream讀書,我創建臨時固定長度char緩衝器,這樣我可以然後通過這個固定長度緩衝器向protobuf的庫中使用ParseFromArray,作爲ParseFromIstream將消耗整個流進行解碼。我真的只想告訴圖書館最多讀取fstreamN字節,但在protobuf中似乎沒有這種功能。 fstream的最多N個字節處傳遞函數的最習慣方法是什麼?或者是我的設計充分顛覆,我應該完全考慮一種不同的方法?

編輯:

  • @codymanix:我鑄造char因爲istream::read需要char數組,如果我沒有記錯。我也沒有使用提取操作符>>,因爲我讀它是與二進制流使用差的形式。或者這是最後一條忠告嗎?
  • @Martin York:刪除new/delete有利於std::vector<char>glob.cpp現在已更新。謝謝!
+0

爲什麼你想要首先將int轉換爲char *? – codymanix 2010-08-18 14:30:48

回答

2

請勿使用new []/delete []。

取而代之的是,我們保留了一個std :: vector作爲釋放的情況。

不要認爲讀數會返回您請求的所有字節。
使用gcount()檢查以確保你得到了你所要求的。

而不是讓Glob根據構造函數中的開關實現輸入和輸出的代碼。而是實現兩個專門的類,如ifstream/ofstream。這將簡化界面和使用。

+0

馬丁 - 謝謝。我實施了前兩項變更,並且我在第三次工作。你對「reinterpret_cast」的使用有任何評論嗎?你相信閱讀fstream到std :: vector 是protobuf的ParseFromArray/ParseFromIstream接口的最佳設計選擇嗎? – 2010-08-18 15:27:13

+0

就我個人而言,在這種情況下,reinterpret_cast <>沒有問題。我認爲它有助於文件,並向讀者提供所需的信息,這是一個危險的演員。但是:我知道我在這個問題上是少數,大多數人會建議你使用static_cast,因爲它具有標準定義的含義,而reinterpret_cast是實現定義的。 – 2010-08-18 15:41:15

+0

讀入矢量。我看不到你有什麼選擇。缺少將自己版本的協議緩衝區分支或(接受主分支機構接受適當的API更改)。從消息中獲取緩衝區並直接寫入該緩衝區(或爲流讀取API提供最大長度)本來是很不錯的。 – 2010-08-18 15:44:50