当前位置: 首页 > wzjs >正文

pc网站建设方案有哪些百度开发者平台

pc网站建设方案有哪些,百度开发者平台,山西网站开发公司电话,网站建设 怎样找客户1. 认识protobuf 序列化概念回顾: 如何实现序列化:xml,json,pb(protobuf) pb: 帮助我们实现序列化的一种手段。 PB的特点 : 语言无关、平台无关:即ProtoBuf支持…

1. 认识protobuf

        序列化概念回顾:

如何实现序列化:xml,json,pb(protobuf)

        pb:  帮助我们实现序列化的一种手段。
PB的特点 :
        语言无关、平台无关:即ProtoBuf支持Java、C++、Python等多种语言,支持多个平台

        高效:即比XML更小、 更快、 更为简单。
        扩展性、兼容性好:你可以更新数据结构,而不影响和破坏原有的旧程序。

使用特点:ProtoBuf是需要依赖通过编译生成的JAVA代码使用的

pb能够通过对message(只定义属性)就可以编译生成相关的java代码。

1.1 windows安装

        Protocol Buffers v21.11,win64版本。

将exe文件目录配置到环境变量中。E:\anzhuangchengxu\protobf\protoc-21.11-win64\bin;

此时在w上安装好了pb的编译器。

此时,确实安装成功。

1.2 在linux(ubuntu环境)安装pb

安装文件C:/Users/缘客扫/Desktop/java笔记/109期精品课/protobuf/protobuf/ProtoBuf%20安装.pdf

         sudo apt-get install autoconf automake libtool curl make g++ unzip -y

下载pb仓库:

将all的连接复制使用指令wget 连接;

下载完成后获得压缩包,使用unzip 压缩包指令进行解压:

如下:

进入pb文件如下:

执行 ./autogen.sh:

修改安装⽬录,统⼀安装在 /usr/local/protobuf 下 ./configure --prefix=/usr/local/protobuf

执行make(15min)

执行make check

Ubuntu 18.04 swap分区扩展_ubuntu18.04 如何查看swapfile文件路径-CSDN博客

发现中途有问题,执行下面的指令

sudo make install

检查是否安装成功:

        对ProtoBuf的完整学习,将使⽤项⽬推进的⽅式,即对于ProtoBuf知识内容的展开,会对 ⼀个项⽬进⾏⼀个版本⼀个版本的升级去讲解ProtoBuf对应的知识点。

1.3 pb的使用流程

需求1:

        编写第⼀版本的通讯录1.0。在通讯录1.0版本中,将实现:

         • 对⼀个联系⼈的信息使⽤PB进⾏序列化,并将结果打印出来。

         • 对序列化后的内容使⽤PB进⾏反序列,解析出联系⼈信息并打印出来。

         • 联系⼈包含以下信息:姓名、年龄。

        通过通讯录1.0,我们便能了解使⽤ProtoBuf初步要掌握的内容,以及体验到ProtoBuf的完整使⽤流 程。

下载下面的三个插件:

步骤1:创建.proto⽂件

        更新contacts.proto(通讯录1.0),新增姓名、年龄字段:

syntax = "proto3";
package start;option java_multiple_files = true;//编译后⽣成的⽂件是否分为多个⽂件
option java_package = "com.example.start";//编译后⽣成⽂件所在的包路径
option java_outer_classname="ContactsProtos";  //编译后⽣成的proto包装类的类名//定义联系⼈消息
message PeopleInfo {string name = 1;int32 age = 2;
}

步骤2:编译contacts.proto⽂件,⽣成JAVA⽂件 编译的⽅式有两种:

        使⽤命令⾏编译;

protoc -I src/main/proto/start --java_out src/main/java contacts.proto

成功编译出java文件。

        使⽤maven插件编译:加入相关依赖

 <plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><!-- 本地安装的protoc.exe的目录 --><protocExecutable>E:\anzhuangchengxu\protobf\protoc-21.11-win64\bin\protoc.exe</protocExecutable><!-- proto文件放置的目录,默认为/src/main/proto --><protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot><!-- 生成文件的目录,默认生成到target/generated-sources/protobuf/ --><outputDirectory>${project.basedir}/src/main/java</outputDirectory><!-- 是否清空目标目录,默认值为true。这个最好设置为false,以免误删项目文件!!! --><clearOutputDirectory>false</clearOutputDirectory></configuration></plugin>

如下图所示,显示编译成功。 

        如上所示,首先1步骤,进入静态方法,进行2步骤对于相关字段进行设置,第三部将构造好的类进行创建,最后使用创建好的类对象进行第四步的序列化和反序列化操作。

        所谓序列化产生的结果都是二进制数据。

需求代码:

package com.example.start;import com.google.protobuf.InvalidProtocolBufferException;import java.util.Arrays;public class FastStart {public static void main(String[] args) throws InvalidProtocolBufferException {PeopleInfo p1 = PeopleInfo.newBuilder().setName("上嘉路").setAge(24).build();// 序列化byte[] bytes = p1.toByteArray();System.out.println("序列化结果为:" + Arrays.toString(bytes));// 反序列化PeopleInfo p2 = PeopleInfo.parseFrom(bytes);System.out.println("反序列化结果为:");System.out.println("姓名:" + p2.getName());System.out.println("年龄:" + p2.getAge());}
}

2. 新增需求2.0

        这个部分会对通讯录进⾏多次升级,使⽤2.x 表⽰升级的版本,最终将会升级如下内容:

         • 不再打印联系⼈的序列化结果,⽽是将通讯录序列化后并写⼊⽂件中。

        • 从⽂件中将通讯录解析出来,并进⾏打印。

         • 新增联系⼈属性,共包括:姓名、年龄、电话信息、地址、其他联系⽅式、备注。

proto3语法中支持在多message并创建的,一支持在message中内嵌创建子message,且这样多个message中的字段编号可以相同。 

代码如下:

// 首行: 语法指定行
syntax = "proto3";
package proto3;option java_multiple_files = true; // 编译后⽣成的⽂件是否分为多个⽂件
option java_package = "com.example.proto3";  // 编译后⽣成⽂件所在的包路径
option java_outer_classname = "ContactsProtos";  // 编译后⽣成的proto包装类的类名import "google/protobuf/any.proto";// 定义联系人 message
message PeopleInfo {// 字段类型 字段名 = 字段唯一编号;string name = 1;int32 age = 2;message Phone {string number = 1;}repeated Phone phone = 3;
}message Contacts {repeated PeopleInfo contacts = 1;
}
package com.example.proto3;import com.google.protobuf.Any;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;public class TestWrite {public static void main(String[] args) throws IOException {Contacts.Builder contactsBuilder = Contacts.newBuilder();// 读取本地已存在的 contacts.bin,反序列化出通讯录对象
//        Contacts contacts = Contacts.parseFrom(
//                new FileInputStream("src/main/java/com/example/proto3/contacts.bin"));
//        contactsBuilder = contacts.toBuilder();try {contactsBuilder.mergeFrom(new FileInputStream("src/main/java/com/example/proto3/contacts.bin"));} catch (FileNotFoundException e) {System.out.println("contacts.bin not find, create new file");}// 向通讯录中新增一个联系人contactsBuilder.addContacts(addPeopleInfo());// 序列化通讯录,将结果写入文件中//将序列化的东西写入到文件流中FileOutputStream outputStream = new FileOutputStream("src/main/java/com/example/proto3/contacts.bin");contactsBuilder.build().writeTo(outputStream);outputStream.close();}private static PeopleInfo addPeopleInfo() {PeopleInfo.Builder builder = PeopleInfo.newBuilder();Scanner scanner = new Scanner(System.in);System.out.println("--------------新增联系人-------------");System.out.print("请输入联系人姓名:");String name = scanner.nextLine();builder.setName(name);System.out.print("请输入联系人年龄:");int age = scanner.nextInt();scanner.nextLine();builder.setAge(age);for (int i = 0;; i++) {System.out.print("请输入联系人电话" + (i + 1) + "(只输⼊回⻋完成电话新增): ");String number = scanner.nextLine();if (number.isEmpty()) {break;}PeopleInfo.Phone.Builder phoneBuilder = PeopleInfo.Phone.newBuilder();phoneBuilder.setNumber(number);builder.addPhone(phoneBuilder);}System.out.println("-------------添加联系人结束-------------");return builder.build();}
}

package com.example.proto3;import com.google.protobuf.InvalidProtocolBufferException;import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;public class TestRead {public static void main(String[] args) throws IOException {// 读取文件,将读取的内容进行反序列化Contacts contacts = Contacts.parseFrom(new FileInputStream("src/main/java/com/example/proto3/contacts.bin"));// 打印printContacts(contacts);// System.out.println(contacts.toString());}private static void printContacts(Contacts contacts) throws InvalidProtocolBufferException {int i = 1;for (PeopleInfo peopleInfo : contacts.getContactsList()) {System.out.println("-----------联系人" + i++ + "--------------");System.out.println("姓名:" + peopleInfo.getName());System.out.println("年龄:" + peopleInfo.getAge());int j = 1;for (PeopleInfo.Phone phone : peopleInfo.getPhoneList()) {System.out.println("电话" + j++ + ": " + phone.getNumber());}}
}

也可以使用静态方法中自带的方法:

 System.out.println(contacts.toString());

3. 新增需求2.1

手机包含类型

枚举是用驼峰命名:

添加电话的类型:

// 首行: 语法指定行
syntax = "proto3";
package proto3;option java_multiple_files = true; // 编译后⽣成的⽂件是否分为多个⽂件
option java_package = "com.example.proto3";  // 编译后⽣成⽂件所在的包路径
option java_outer_classname = "ContactsProtos";  // 编译后⽣成的proto包装类的类名import "google/protobuf/any.proto";// 定义联系人 message
message PeopleInfo {// 字段类型 字段名 = 字段唯一编号;string name = 1;int32 age = 2;message Phone {string number = 1;// 0值必须存在,且作为第一个枚举常量的值// 枚举值范围:32位整数范围,不要设置负数enum PhoneType {MP = 0;  // 移动电话TEL = 1; // 固定电话}PhoneType type = 2;}repeated Phone phone = 3;
}
message Contacts {repeated PeopleInfo contacts = 1;
}

进行读写相关代码修改之后操作:

读取文件,获取相关内容:

反序列化的过程中,对于输入时没有进行设置类型的参数,会直接赋予默认值的类型。

any类型的message文件:在使用的时候将any类型理解为泛型。

4. 新增需求2.2

通讯录包含地址信息

在proto文件中添加相关字段:

message Address {string home_address = 1;string unit_address = 2;
}

写方法添加下面字段:

Address.Builder addressBuilder = Address.newBuilder();System.out.print("请输入联系人家庭地址:");String homeAddress = scanner.nextLine();addressBuilder.setHomeAddress(homeAddress);System.out.print("请输入联系人单位地址:");String unitAddress = scanner.nextLine();addressBuilder.setUnitAddress(unitAddress);builder.setData(Any.pack(addressBuilder.build()));System.out.println("-------------添加联系人结束-------------");return builder.build();

 

 内容读取方法添加:

  if (peopleInfo.hasData()&& peopleInfo.getData().is(Address.class)) {Address address = peopleInfo.getData().unpack(Address.class);if (!address.getHomeAddress().isEmpty()) {System.out.println("家庭地址:" + address.getHomeAddress());}if (!address.getUnitAddress().isEmpty()) {System.out.println("单位地址:" + address.getUnitAddress());}}

5. 新增需求2.3

        新增其他需求,其他联系方式,qq或wx,oneof字段加强多选一的行为,且不支持repeated字段。

写操作:

读操作:

6. 新增需求2.4

使用map类型增加备注信息。

6. 默认值

• 对于字符串,默认值为空字符串。

• 对于字节,默认值为空字节。

• 对于布尔值,默认值为false。

• 对于数值类型,默认值为0。

• 对于枚举,默认值是第⼀个定义的枚举值,必须为0。

• 对于消息字段,未设置该字段。它的取值是依赖于语⾔。

• 对于设置了repeated的字段的默认值是空的(通常是相应语⾔的⼀个空列表)。

• 对于 消息字段、 oneof 字段 和 any 字段 ,都有has⽅法来检测当前字段是否被设置。

新增字段:注意新增的字段不和老字段冲突:名称和字段标号。

修改老字段:

        禁⽌修改任何已有字段的字段编号。

        • 若是移除⽼字段,要保证不再使⽤移除字段的字段编号。正确的做法是保留字段编号 (reserved),以确保该编号将不能被重复使⽤。不建议直接删除或注释掉字段。

         • int32,uint32,int64,uint64和bool是完全兼容的。可以从这些类型中的⼀个改为另⼀个, ⽽不破坏前后兼容性。若解析出来的数值与相应的类型不匹配,可能会被截断(例如,若将64 位整数当做32位进⾏读取,它将被截断为32位)。

        • sint32和sint64相互兼容但不与其他的整型兼容。

         • string和bytes在合法UTF-8字节前提下也是兼容的。

        • bytes包含消息编码版本的情况下,嵌套消息与bytes也是兼容的。

        • fixed32与sfixed32兼容,fixed64与sfixed64兼容。

        • enum 与int32,uint32,int64和uint64兼容(注意若值不匹配会被截断)。但要注意当反序 列化消息时会根据语⾔采⽤不同的处理⽅案:例如,未识别的proto3枚举类型会被保存在消息 中,但是当消息反序列化时如何表⽰是依赖于编程语⾔的。整型字段总是会保持其的值。

        • oneof:

        ◦ 将⼀个单独的值更改为新oneof类型成员之⼀是安全和⼆进制兼容的。

         ◦ 若确定没有代码⼀次性设置多个值那么将多个字段移⼊⼀个新oneof类型也是可⾏的。

        ◦ 将任何字段移⼊已存在的oneof类型是不安全的

 删除老字段:不建议直接删除老字段,若是移除老字段,要保证不再使用移除字段的字段编号。

        .proto文件在进行反编译数据时,不是按照字段名来进行编译的,而是按照字段标号来进行编译相关内容的。

 保留字段reserved:

         如果通过删除或注释掉字段来更新消息类型,未来的⽤⼾在添加新字段时,有可能会使⽤以前已经 存在,但已经被删除或注释掉的字段编号。将来使⽤该.proto的旧版本时的程序会引发很多问题:数 据损坏、隐私错误等等。

        确保不会发⽣这种情况的⼀种⽅法是:使⽤ reserved 将指定字段的编号或名称设置为保留项。当 我们再使⽤这些编号或名称时,protocolbuffer的编译器(在进行编译时)将会警告这些编号或名称不可⽤。reserved 可以一次性保留多个字段编号,期间使用逗号隔开。也可以保留字段命。

        未知字段:解析结构良好的protocolbuffer已序列化数据中的未识别字段的表⽰⽅式。例如,当 旧程序解析带有新字段的数据时,这些新字段就会成为旧程序的未知字段。

7. 前后兼容性

        根据上述的例⼦可以得出,pb是具有向前兼容的。为了叙述⽅便,把增加了“⽣⽇”属性的service 称为“新模块”;未做变动的client称为“⽼模块”。

        • 向前兼容:⽼模块能够正确识别新模块⽣成或发出的协议。这时新增加的“⽣⽇”属性会被当作未 知字段(pb3.5版本及之后)。

        • 向后兼容:新模块也能够正确识别⽼模块⽣成或发出的协议。

        前后兼容的作⽤:当我们维护⼀个很庞⼤的分布式系统时,由于你⽆法同时升级所有模块,为了保证 在升级过程中,整个系统能够尽可能不受影响,就需要尽量保证通讯协议的“向后兼容”或“向前兼 容”。

        选项option .proto ⽂件中可以声明许多选项,使⽤ option 标注。选项能影响proto编译器的某些处理⽅式。

        选项分为⽂件级、消息级、字段级等等,但并没有⼀种选项能作⽤于所有的类型。

java_multiple_files:编译后⽣成的⽂件是否分为多个⽂件,该选项为⽂件选项。

java_package:编译后⽣成⽂件所在的包路径,该选项为⽂件选项。

java_outer_classname:编译后⽣成的proto包装类的类名,该选项为⽂件选项。

allow_alias:允许将相同的常量值分配给不同的枚举常量,⽤来定义别名。该选项为枚举选项。

 8. 通讯录4.0实现---⽹络版

需求如下:
         客户端:向服务端发送联系人信息,并接收服务端返回的响应。

        服务端:接收到联系人信息后,将结果打印出来
        客户端、服务端间的交互数据使用Protobuf来完成

代码环境:Maven项⽬+ UDP数据报套接字编程

客户端和服务器交互逻辑:

代码和结果略。

9. 总结

序列化能⼒对⽐

         • 编解码性能:ProtoBuf>jackson>fastjson2。

        • 内存占⽤:ProtoBuf>jackson~=fastjson2。

all in all:

⼩结:

        1. XML、JSON、ProtoBuf都具有数据结构化和数据序列化的能⼒。

        2. XML、JSON更注重数据结构化,关注可读性和语义表达能⼒。ProtoBuf更注重数据序列化,关注 效率、空间、速度,可读性差,语义表达能⼒不⾜,为保证极致的效率,会舍弃⼀部分元信息。

        3. ProtoBuf的应⽤场景更为明确,XML、JSON的应⽤场景更为丰富。

ps:本文仅用来自己整理学习时的笔记。 

http://www.dtcms.com/wzjs/262068.html

相关文章:

  • 国家补贴软件网站开发政策资深seo顾问
  • 西渡网站建设发外链的网址
  • 网站浏览器兼容性友情链接网
  • 专业广州做网站公司广告推广软件
  • 武汉做网站找谁乌鲁木齐seo
  • 棋牌游戏平台爱站seo查询软件
  • vps被攻击网站打不开ping值高台州网站制作维护
  • b2b网站制作永久不收费免费的聊天软件
  • 武汉网站建站怎样下载优化大师
  • 电脑网站建设在哪里十大嵌入式培训机构
  • 手机asp网站营销咨询服务
  • 做网站时背景图片浮动超能搜索引擎系统网站
  • 长葛网站建设东莞seo排名扣费
  • 做视频网站 服务器配置app推广方式有哪些
  • 零基础平面设计教程前端seo主要优化哪些
  • 返佣网站都是自己做的免费b站动漫推广网站2023
  • 大连网站排名优化价格兰州网站seo服务
  • 优秀品牌企业网站建设案例关键词优化seo多少钱一年
  • notepad做网站国内能用的搜索引擎
  • 手机网站开发 视频网络营销与电子商务的区别
  • 公司做网站广告语利尔化学股票
  • wordpress文档南宁百度seo推广
  • 广州网站建设专家国内搜索引擎排名第一
  • php实验报告企业网站开发温州最好的seo
  • 大学文明校园网站建设方案百度怎样发布作品
  • wordpress的分类东莞网站优化公司
  • 哪个网站可以做曝光台googleplay商店
  • 网页设计 武汉合肥网站优化公司
  • 备案网站名称怎么改企业培训课程推荐
  • wordpress公司网站性价比高的seo网站优化