电子商务网站建设过程报告,直播软件排名,网站运营 宣传团队建设,修改仪表盘WordPress一、序列化概念回顾 二、什么是PB
将结构化数据进行序列化的一种方式
三、PB的特点
语言无关、平台无关#xff1a;即PB支持Java#xff0c;C、Python等多种语言。支持多个平台
高效#xff1a;即比XML更小#xff0c;更快#xff0c;更为简单。
扩展性、兼容性好即PB支持JavaC、Python等多种语言。支持多个平台
高效即比XML更小更快更为简单。
扩展性、兼容性好你可以更新数据结构而不影响和破坏原有的旧程序。
使用特点ProtoBuf是需要依赖通过编译生成的头文件和源文件来使用。 四、安装ProtoBuf
ProtoBuf下载地址https://github.com/protocolbuffers/protobuf/releases
1、在windows安装
配置一下环境变量就可以了 protoc --version 打印出版本
2、在ubuntu下安装
下载依赖器 下载protoBuf 解压包 unzip
编译生成protobuf 一次执行下面的命令 大概需要半个小时左右 这里需要更改profile修改环境变量
sudo vim /etc/profile
在里面添加下面的内容
#(动态库搜索路径) 程序加载运⾏期间查找动态链接库时指定除了系统默认路径之外的其他路径export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/usr/local/protobuf/lib/
#(静态库搜索路径) 程序编译期间查找动态链接库时指定查找共享库的路径
export LIBRARY_PATH$LIBRARY_PATH:/usr/local/protobuf/lib/
#执⾏程序搜索路径
export PATH$PATH:/usr/local/protobuf/bin/
#c程序头⽂件搜索路径
export C_INCLUDE_PATH$C_INCLUDE_PATH:/usr/local/protobuf/include/
#c程序头⽂件搜索路径
export CPLUS_INCLUDE_PATH$CPLUS_INCLUDE_PATH:/usr/local/protobuf/include/
#pkg-config 路径
export PKG_CONFIG_PATH/usr/local/protobuf/lib/pkgconfig/
再执行这个命令
source /etc/profile
另外需要说一下Centos用户在安装的时候需要用到这个命令
sudo yum install autoconf automake libtool curl make gcc-c unzip
五、使用ProtoBuf
使用protobuf实现一个通讯录项目一个版本一个版本的实现从而有效推进protobuf的学习。
快速上手
目的完整使用PB学习基本语法。 在快速上手中我们会编写第一个版本的通讯录1.0。 • 对⼀个联系⼈的信息使⽤PB进⾏序列化并将结果打印出来。 • 对序列化后的内容使⽤PB进⾏反序列解析出联系⼈信息并打印出来。 • 联系⼈包含以下信息:姓名、年龄。 通过通讯录1.0我们便能了解使⽤ProtoBuf初步要掌握的内容以及体验到ProtoBuf的完整使⽤流程。 步骤一创建.protobuf 步骤二进行编译 -I 指定搜索目录
步骤三
对一个联系人的信息使用PB进行序列化并将结果打印出来。
对序列化后的内容使用PB进行反序列化解析出联系人信息并打印出来。 六、proto3语法详解 升级版本的通讯录 • 不再打印联系⼈的序列化结果⽽是将通讯录序列化后并写⼊⽂件中。 • 从⽂件中将通讯录解析出来并进⾏打印。 • 新增联系⼈属性共包括姓名、年龄、电话信息、地址、其他联系⽅式、备注。 1、字段规则、消息类型的定义和使用
新增联系人的属性。
repeated来定义一个数组。消息中可以包含该字段任意多次包括零次其中重复值的顺序会被保留。可以理解为定义了⼀个数组。
singular的规则消息中可以包含该字段零次或⼀次不超过⼀次。proto3语法中字段默认使⽤该规则。 可以嵌套定义message。
引入 phone文件 定义通讯录proto文件 把通讯录的信息写入文件首先编写makefile文件。 里面调用的函数返回的是一个已经开辟好的空间所以我们可以使用这个空间直接对contact新增联系人。 查看二进制文件 读取文件 decode的使用 2、proto3语法理解enum类型
0必须存在必须在第一个。 也可以定义在消息体内 不能让同级的enum类型中的成员系统多个文件中的enum类型中的类型也不能同名。会编译报错。解决方法可以包含一个命名空间进行隔离。 通讯录2.1更新proto文件 设置联系人电话类型 修改打印函数 枚举类型会被默认设置。反序列化时会设置枚举值为0的枚举类型。
3、Any类型的讲解
Any类型可以被理解为是一个泛型类型。可以存储任意的消息类型。
通讯录2.2版本 使用Any字段存放联系人地址。 新增联系人地址 读出联系人地址 4、oneof类型讲解
2.3版本新增其他联系方式
只能设置一个其他联系方式 字段编号不能重复不能使用repeated来修饰里面的值
添加联系人的其他联系方式 读取联系人的其他联系方式 5、map类型的使用
2.4版本增加备注
不能使用repeated来修饰设置的kv值是无序的 设置联系人备注信息 打印备注信息 6、默认值讲解
反序列化消息时如果被反序列化的⼆进制序列中不包含某个字段反序列化对象中相应字段时就会设置为该字段的默认值。不同的类型对应的默认值不同 • 对于字符串默认值为空字符串。 • 对于字节默认值为空字节。 • 对于布尔值默认值为false。 • 对于数值类型默认值为0。 • 对于枚举默认值是第⼀个定义的枚举值必须为0。 • 对于消息字段未设置该字段。它的取值是依赖于语⾔。• 对于设置了repeated的字段的默认值是空的通常是相应语⾔的⼀个空列表。 • 对于 消息字段 、 oneof字段 和 any字段 C和Java语⾔中都有has_⽅法来检测当前字段是否被设置。 对于标量数据类型在proto3语法下没有生成has_方法。不确定是用户设置的还是一个默认值。
7、更新消息
新增字段
注意不要和老字段冲突即可
修改字段 • 禁⽌修改任何已有字段的字段编号。 • 若是移除⽼字段要保证不再使⽤移除字段的字段编号。正确的做法是保留字段编号 reserved以确保该编号将不能被重复使⽤。不建议直接删除或注释掉字段。 • int32uint32int64uint64和bool是完全兼容的。可以从这些类型中的⼀个改为另⼀个 ⽽不破坏前后兼容性。若解析出来的数值与相应的类型不匹配会采⽤与C⼀致的处理⽅案例如若将64位整数当做32位进⾏读取它将被截断为32位。 • sint32和sint64相互兼容但不与其他的整型兼容。• string和bytes在合法UTF-8字节前提下也是兼容的。 • bytes包含消息编码版本的情况下嵌套消息与bytes也是兼容的。 • fixed32与sfixed32兼容fixed64与sfixed64兼容。 • enum与int32uint32int64和uint64兼容注意若值不匹配会被截断。但要注意当反序 列化消息时会根据语⾔采⽤不同的处理⽅案例如未识别的proto3枚举类型会被保存在消息中但是当消息反序列化时如何表⽰是依赖于编程语⾔的。整型字段总是会保持其的值。 • oneof ◦ 将⼀个单独的值更改为新oneof类型成员之⼀是安全和⼆进制兼容的。 ◦ 若确定没有代码⼀次性设置多个值那么将多个字段移⼊⼀个新oneof类型也是可⾏的。 ◦ 将任何字段移⼊已存在的oneof类型是不安全的。 删除字段
不能直接删除已存在的字段 如果要删除老子段要保证不使用已经被删除的或者已经被注释掉的字段编号会导致下列问题 如何不使用已经被注释掉的字段编号呢
reserved保留项
指定保留的字段编号 会有一个错误发生 还可以这样写 结果我们看到年龄不在使用前面的字段编号了 上面的生日信息哪里去了呢。被存放到了未知字段中。
未知字段
未知字段是什么 • 未知字段解析结构良好的protocolbuffer已序列化数据中的未识别字段的表⽰⽅式。例如当旧程序解析带有新字段的数据时这些新字段就会成为旧程序的未知字段。 • 本来proto3在解析消息时总是会丢弃未知字段但在3.5版本中重新引⼊了对未知字段的保留机制。所以在3.5或更⾼版本中未知字段在反序列化时会被保留同时也会包含在序列化的结果中。 从哪获取未知字段
通过Reflection类中UnKnowFields()方法获取 打印未知字段 前后兼容性 • 向前兼容⽼模块能够正确识别新模块⽣成或发出的协议。这时新增加的“⽣⽇”属性会被当作未 知字段pb 3.5版本及之后。 • 向后兼容新模块也能够正确识别⽼模块⽣成或发出的协议。 前后兼容的作⽤当我们维护⼀个很庞⼤的分布式系统时由于你⽆法同时 升级所有 模块为了保证 在升级过程中整个系统能够尽可能不受影响就需要尽量保证通讯协议的“向后兼容”或“向前兼容”。 8、option选项语法详解 option选项可以影响ProtoBuf的编译属性。用的不太多所以我们可以用文档看一下就可以了。
七、通讯录4.0实现 --- 网络版
服务器 客户端 客户端调用接口req调用返回resp。 客户端的.proto文件和服务器的相同
客户端的菜单编写 服务端书写 add del findALL findOne接口。每个接口会有reqresp协议。
序列化req
调用接口
反序列化req 新增一个联系人持久化存储通讯录
序列化resp
反序列化resp
AddContact方法
protobuf远远比json的序列化和反序列化效率高。json的内存占用比protobuf多一倍。