做音响的是哪个网站,怎样做淘宝客网站,做网站用php还是jsp,西安小程序开发哪家好这里写目录标题 前言1. 序列化1.1 网络通信中的问题分析1.2 常用的序列化方式 2. protobuf2.1 操作流程 总结 前言 Protocol Buffers#xff08;protobuf#xff09;是一种轻量级的数据交换格式#xff0c;可以用于结构化数据的序列化和反序列化。它使用二进制格式来编码数据… 这里写目录标题 前言1. 序列化1.1 网络通信中的问题分析1.2 常用的序列化方式 2. protobuf2.1 操作流程 总结 前言 Protocol Buffersprotobuf是一种轻量级的数据交换格式可以用于结构化数据的序列化和反序列化。它使用二进制格式来编码数据以提高传输效率和数据压缩比。 在protobuf中我们可以使用.proto文件来定义消息类型并使用编译器生成针对各种编程语言的序列化和反序列化代码。序列化是将结构化数据转换为一系列字节的过程反序列化则是将字节流解析为结构化数据的过程。 序列化的过程通常涉及以下步骤 定义消息类型使用.proto文件定义消息类型和字段。 编写应用程序编写应用程序创建消息对象并填充字段。 序列化数据使用protobuf库将消息对象序列化为字节数组。 传输数据将字节数组发送给接收方。 反序列化数据接收方使用protobuf库将字节数组反序列化为消息对象并访问其中的字段。 在序列化过程中protobuf使用压缩技术来减小数据的大小从而提高传输效率。此外protobuf支持向前和向后兼容的特性可以使得我们在更新消息类型时不会破坏现有的序列化数据 1. 序列化
序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程与之相对应的过程称之为反序列化Unserialization。序列化和反序列化主要用于解决在跨平台和跨语言的情况下, 模块之间的交互和调用但其本质是为了解决数据传输问题。 实现数据序列化: 要有原始数据 复合类型 - 最常见的情况基础数据类型 通过某些方式 - 另外一种形式的数据得到的数据干啥? - 目的: 进行分发, 分发到不同的终端/平台, 保证不同的平台能正确解析 网络传输磁盘拷贝 序列化目的不是为了加密, 为的是数据的跨平台传输 序列化的整体过程: 发送端 原始数据 - 序列化 (编码) - 特殊格式的字符串发送这个字符串 接收端: 接收数据特殊格式的字符串 - 反序列化 (解码) - 原始数据对原始数据进行处理 1.1 网络通信中的问题分析
发送过程中遇到的一些问题? 平台不同 如果不是字符串, 需要进行字节序转换 语言不同 字节对齐问题
1.2 常用的序列化方式 XML Extensible Markup Language 类似于html XML是一种常用的序列化和反序列化协议具有跨机器跨语言等优点。XML历史悠久其1.0版本早在1998年就形成标准并被广泛使用至今。 XML的最初产生目标是对互联网文档进行标记所以它的设计理念中就包含了对于人和机器都具备可读性。 但是当这种标记文档的设计被用来序列化对象的时候就显得冗长而复杂。 XML基本格式: ?xml version1.0 encodingutf-8?LibraryType name小说Book authorJ.K.ROWLING price12$哈利波特1/BookBook authorJ.K.ROWLING price12$哈利波特2/BookBook authorJ.K.ROWLING price12$哈利波特3/BookBook authorJ.K.ROWLING price12$哈利波特4/Book/TypeType name历史Book author司马迁 price20$史记/Book/Type/LibraryJson JavaScript Object Notation
JSON起源于弱类型语言Javascript它的产生来自于一种称之为关联数组Associative array的概念其本质是就是采用键值对的方式来描述对象。
JSON格式保持了XML的人眼可读的优点非常符合工程师对对象的理解。
相对于XML而言序列化后的数据更加简洁XML所产生序列化之后文件的大小接近JSON的两倍而且其协议比较简单解析速度比较快。
JSON格式具备Javascript的先天性支持所以被广泛应用于Web browser的应用常景中是Ajax的事实标准协议。
// json是一种数据格式, 不是语言, 和平台语言无关
// json数组
[整形, 浮点型, 布尔类型, 字符串, json数组, json对象]
[12, 12.44, true, hello, [1,2,3]]
// json对象
{key:value
}
json对象中是n个键值对
key: 必须是字符串
value: 整形浮点型布尔字符串json数组json对象注意事项:在一个文件中只能存储一个大的数组或者对象, 但是可以嵌套使用原素和原始之间使用逗号间隔(一个键值对视为一个元素)最后一个元素后边没有逗号{lilii:717,tom:nihao,lucy:yyyyhhhh
}[洁洁, 姐姐]{洁洁:{father:张三,mother:xxx,sisterxxx,favorite:[跳舞, 唱歌, 游泳]}姐姐:{}
}Protocol Buffer ASN.1 抽象语法标记(Abstract Syntax Notation One) boost 序列化的类
2. protobuf Protobuf是一个纯粹的展示层协议可以和各种传输层协议一起使用Protobuf的文档也非常完善。google 提供了多种语言的实现java、c#、c、go 和 python每一种实现都包含了相应语言的编译器以及库文件。 Protobuf支持的数据类型相对较少不支持常量类型。由于其设计的理念是纯粹的展现层协议目前并没有一个专门支持Protobuf的RPC框架。 2.1 操作流程
准备数据 复合类型: 结构体/ 类 基础类型创建一个新文件 xxx.proto将我们要序列化的数据 - 写入到proto文件 注意写入有语法格式 通过命令 protoc将xxx.proto文件生成一个c的类 会生成一个头文件/ 源文件操作命令- 在window终端中: protoc xxx.proto --cpp_out./ 使用这两个文件 文件里有对数据操作的api 读数据 API 方法名字 变量名() 写数据 API方法名字: set_变量名(arg)等等API
// 要序列化的数据
struct Persion
{int id;string name;string sex; // man womanint age;
};int id;在.proto文件中定义消息格式 // protobuf的版本
syntax proto3; // proto2
// 组织Persion结构体
// 语法格式
message 关键字(相当于被创建出的类的名字)
{// 成员变量数据类型 变量名 变量的编号; // 编号从1开始, 不能重复
}// .proto文件 生成 c 类的命令
protoc proto文件名 --cpp_out生成目录具体转换类型规则如下所示
.proto类型C类型备注doubledouble64位浮点数floatfloat32位浮点数int32int3232位整数int64int6464位整数uint32uint3232位无符号整数uint64uint6464位无符号整数sint32sint3232位整数处理负数效率比int32更高sint64sint6464位整数处理负数效率比int64更高fixed32uint32总是4个字节。如果数值总是比总是比228大的话这个类型会比uint32高效。fixed64uint64总是8个字节。如果数值总是比总是比256大的话这个类型会比uint64高效。sfixed32int32总是4个字节sfixed64int64总是8个字节boolbool布尔类型stringstring一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本bytesstring处理多字节的语言字符、如中文enumenum枚举messageobject of class自定义的消息类型
repeated限定修饰符
用于定义一个字段可以包含多个值。它只能应用于特定的字段类型例如int32、string等。
使用repeated修饰符可以定义一个重复字段表示该字段可以包含一个或多个值并以列表的形式进行存储和传输。这使得我们能够在一个字段中存储多个相关的数据而无需定义多个独立的字段。
以下是一个示例展示了如何使用repeated修饰符创建一个重复字段
message MyMessage {repeated int32 numbers 1;repeated string names 2;
}在上述示例中numbers字段和names字段都被修饰为repeated允许存储多个整数和字符串值。
通过使用repeated修饰符我们可以轻松地处理包含多个值的字段例如迭代访问、添加和删除元素等操作。
枚举
枚举类型是一种定义常量值列表的方式用于表示一组相关的命名常量。它可以在消息类型中定义并用于描述消息类型中的字段。
以下是一个示例展示了如何使用protobuf中的枚举类型 // 定义枚举
enum PhoneType {MOBILE 0;// protbuf中第一个枚举值必须为0HOME 1;WORK 2;
}message Person {string name 1;repeated PhoneNumber phones 2;
}message PhoneNumber {string number 1;PhoneType type 2; // 枚举变量
}在上述示例中我们定义了一个PhoneType枚举类型其中包含三个常量值MOBILE、HOME和WORK。这个枚举类型用于描述电话号码的类型包括移动电话、家庭电话和工作电话。
然后我们在PhoneNumber消息类型中使用了这个枚举类型将电话号码与电话类型关联起来。这样我们就可以轻松地区分不同类型的电话号码并按照类型进行处理。
在protobuf中枚举类型的值对应一个整数可以使用操作符为其指定具体的值。默认情况下第一个枚举值的值为0后续的枚举值依次递增。如果需要指定特定的值可以使用类似于MY_ENUM_VALUE 100;这样的语法进行设置。 proto文件的导入 // Persion.proto
syntax proto3;
// 导入另外一个proto文件
import Info.proto;enum Color
{Red 0; // protbuf中第一个枚举值必须为0Green 6;Blue 9;
}message Persion
{int32 id 1; // 编号从1开始repeated bytes name 2;string sex 3;int32 age 4;Color color 5;Info info 6; // Info对象, 导入的proto文件中的类
}// Info.proto
syntax proto3;message Info
{bytes address 1; // 地址int32 number 2; // 门牌号
}包 - 命名空间 // Persion.proto
syntax proto3;
// 导入另外一个proto文件
import Info.proto;
// 添加命名空间
package itcast; // Persion类属于itcast这个命名空间enum Color
{Red 0; // protbuf中第一个枚举值必须为0Green 6;Blue 9;
}message Persion
{int32 id 1; // 编号从1开始repeated bytes name 2;string sex 3;int32 age 4;Color color 5;// 命名空间.类名itheima.Info info 6; // Info对象, 导入的proto文件中的类
}// Info.proto
syntax proto3;
// Persion类属于itheima这个命名空间
package itheima;message Persion
{bytes address 1; // 地址int32 number 2; // 门牌号
}使用protobuf编译器生成C类 # protobuf编译器, 编译源码得到的 protoc.exe
# 语法
# --cpp_out 生成的c类的位置
protoc.exe xxx.proto --cpp_out目录使用C API来读写消息 读: 变量名()写: set_变量名(arg1, arg2, ...)
总结 效率和紧凑性protobuf使用二进制编码提供了高效的数据传输和紧凑的数据存储相对于文本格式可以节省带宽和存储空间。 跨平台和可扩展性protobuf支持多种编程语言包括C、Java、Python等可以在不同平台和语言之间进行数据交换。它还支持向前和向后兼容可以在消息类型更新时保持数据的兼容性。 结构化数据定义protobuf使用.proto文件来定义消息类型和字段提供了结构化的数据模型使得数据的组织和访问更加清晰和灵活。 强类型和类型安全protobuf使用强类型系统可以在编译时检查类型错误避免在运行时出现错误。这提供了更好的类型安全性和代码可靠性。 支持多种数据类型protobuf支持各种基本数据类型如整数、字符串、布尔值等以及复杂的数据类型如嵌套消息、枚举等可以灵活地描述和处理各种数据结构。 序列化和反序列化protobuf提供了自动生成的序列化和反序列化代码使得数据的序列化和反序列化过程简单而高效。它还支持压缩技术可以减小数据大小提高传输效率。 可读性和可维护性由于protobuf使用结构化的数据模型和明确的消息类型定义使得代码更具可读性和可维护性。同时它也提供了版本控制机制方便进行更新和演进。