Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 协议缓冲区是否可以部分更新?_C++_Protocols_Protocol Buffers_Updates - Fatal编程技术网

C++ 协议缓冲区是否可以部分更新?

C++ 协议缓冲区是否可以部分更新?,c++,protocols,protocol-buffers,updates,C++,Protocols,Protocol Buffers,Updates,我是protobuf的新手,我的问题是:协议缓冲区是否支持部分更新 例如,我有这样的信息: package model.test; message Person{ required int32 id = 1; required string name = 2; repeated PhoneNumber phone = 3; } enum PhoneType{ MOBILE = 0; HOME = 1; WORK = 2; } message

我是protobuf的新手,我的问题是:协议缓冲区是否支持部分更新

例如,我有这样的信息:

package model.test;

message Person{
    required int32 id = 1;
    required string name = 2;
    repeated PhoneNumber phone = 3;
}

enum PhoneType{
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
}

message PhoneNumber{
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
} 
现在我得到的数据如下:

model::test::Person person;
person.set_id(1);
person.set_name("Jack");

model::test::PhoneNumber* _phone3 = person.add_phone();
_phone3->set_number("123567");
_phone3->set_type(model::test::MOBILE);

model::test::PhoneNumber* _phone4 = person.add_phone();
_phone4->set_number("347890");
_phone4->set_type(model::test::WORK);
这种情况是,当只有
工作电话号码
更改时,我必须使用以下代码更新整个
person
对象

fstream out("User.txt", ios::out | ios::binary | ios::trunc);
person.SerializePartialToOstream(&out);

但这样做是没有效率的。我只想更新
电话号码
,protolbuf或类似的东西中是否有任何部分更新

我认为没有人支持你想做的事。如果您仔细想想,首先存在某种部分更新序列化是没有意义的。为了使protobuf能够操作在磁盘上的文件中序列化的对象,它需要读取并反序列化整个对象,以便知道以前填充了哪些字段。然后,当序列化更新的对象并将其写回磁盘时,无论您做什么,都必须覆盖旧文件(即,如果不完全覆盖原始文件,就无法将额外字节插入文件系统中的文件)。

协议缓冲区的设计实际上使串联与合并相同,合并时最后一个字段获胜(添加的
重复的
除外)。在您的情况下,您实际上应该能够序列化一个只包含电话号码集的blob,并附加此数据,它将覆盖先前的值。但是,这仅适用于根对象。哪个是你的:不是。而且它不适用于重复的
,而你的:是。

哇,不知道最后一个字段的行为。整洁的看起来我应该删除我的答案。实际上,我认为你应该保留你的答案——因为它仍然是正确的,因为OP想要更改的数字不在根上。另外:这不适用于重复的
@marcgravel,谢谢你的好回答。但是,我仍然不清楚您提到的关于
电话号码
blob和
附加
此数据的内容。如何将其附加到
人员
?以及如何组织个人信息?@zangw如果
电话
可选的
必需的
,而不是
重复的
,那么您只需创建一个新的
个人
,创建并分配一个新的
电话号码
,并设置
编号
,然后将其序列化到旧流的末尾,然后它将自动包含在反序列化中。但是,由于它是重复的,这将不起作用-第二个
电话号码
实例将被追加,而不是合并。