1、给经常使用的标签设置在1-15
As you can see, each field in the message definition has a unique numbered tag. These tags are used to identify your fields in the message binary format, and should not be changed once your message type is in use. Note that tags with values in the range 1 through 15 take one byte to encode, including the identifying number and the field’s type (you can find out more about this in Protocol Buffer Encoding). Tags in the range 16 through 2047 take two bytes. So you should reserve the tags 1 through 15 for very frequently occurring message elements. Remember to leave some room for frequently occurring elements that might be added in the future.
2、标签的最大与最小值,已经保留的标签
The smallest tag number you can specify is 1, and the largest is
229−1
, or 536,870,911. You also cannot use the numbers 19000 though 19999 (FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber), as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your .proto. Similarly, you cannot use any previously reserved tags.
3、Fiel rules
- required: a well-formed message must have exactly one of this field.
- optional: a well-formed message can have zero or one of this field (but not more than one).
- repeated: this field can be repeated any number of times (including zero) in a well-formed message.The order of the repeated values will be preserved.
-
For historical reasons, repeated fields of scalar numeric types aren’t encoded as efficiently as they could be. New code should use the special option [packed=true] to get a more efficient encoding. For example:
repeated int32 samples = 4 [packed=true];//这种方式可以使得编码效率变好,针对与repeated
4、不推荐使用required
Some engineers at Google have come to the conclusion that using required does more harm than good; they prefer to use only optional and repeated.
5、Reserved Fields
示列
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
6、数据类型
7、简单例子实现
proto书写
syntax = "proto2";
package test;
message people {
optional string name = 1;
optional int32 id = 2;
}
protoc test.proto --cpp_out=./
测试代码:
#include <google/protobuf/text_format.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include "test.pb.h"
#include <iostream>
#include <fstream>
#include <fcntl.h>//open 函数所有的头
#include <unistd.h>//close 函数所在的头
using namespace std;
using namespace test;
int main(){
people me;
me.set_name("yang");
me.set_id(22);
cout << me.name() << " " << me.id() << endl;
people her;
her.CopyFrom(me);
cout << her.name() << " " << her.id() << endl;
fstream output("./log", ios::out);
me.SerializeToOstream(&output);
output.close();
fstream input("./log", ios::in);
people temp;
temp.ParseFromIstream(&input);
cout << temp.name() << " " << temp.id() << endl;
int fd = open("yang",O_RDONLY);
google::protobuf::io::FileInputStream* inputf = new google::protobuf::io::FileInputStream(fd);
google::protobuf::TextFormat::Parse(inputf,&temp);
cout << temp.name() << " " << temp.id() << endl;
delete inputf;
close(fd);
fd = open("temp", O_WRONLY | O_CREAT | O_TRUNC, 0644);
temp.set_name("yang");
temp.set_id(22);
google::protobuf::io::FileOutputStream* outputf = new google::protobuf::io::FileOutputStream(fd);
google::protobuf::TextFormat::Print(temp, outputf);
delete outputf;
close(fd);
return 1;
}
makefile
test:
g++ -o test test.cpp test.pb.cc -I. -lprotobuf