2010-08-18 155 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