文档章节

protocol buffer使用

RandomObject
 RandomObject
发布于 07/08 15:53
字数 989
阅读 50
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

protocol buffer使用例子

protocol buffer是什么

https://developers.google.com/protocol-buffers 这是protocol buffer的官方网站,上边有详细的使用方式。
一般常见的序列和反序列方式就是json和xml了,还有Java原生的Serializable,protocol buffer效率和体积更小,故使用场景一般为游戏,即时通讯等宽带环境不好,要求比较高得场景。

摘抄自百度百科

protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

windows下安装protocol buffer

https://github.com/protocolbuffers/protobuf/releases 需要下载windows版的protocol buffer工具

下载完毕以后,就是正常的配置环境变量,方便后续的编译

这是解压后的文件目录,protoc.exe就是需要配置环境变量的
此次测试设置的环境变量地址为C:\Users\peipe\Downloads\protoc-3.12.3-win64\bin

查看环境变量是否设置成功

出现此信息,配置成功。

测试开始

创建需要序列化的java类

import lombok.Data;

import java.io.Serializable;

@Data
public class Person implements Serializable {

    /**姓名*/
    private String name;
    /**年龄*/
    private int age;
    /**电话号码*/
    private String phoneNum;
    /**身高*/
    private double height;
    /**性别*/
    private boolean sex;

}

package com.gitee.asand;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Arrays;

@Slf4j
public class App {

    public static void main(String[] args) throws IOException {
        log.info("[测试jdk,json,protocolbuffer三种方式的优劣]");
        Person person = create();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(out);
        oos.writeObject(person);
        oos.flush();
        log.info("[jdk方式======》start]");
        System.out.println(Arrays.toString(out.toByteArray()));
        System.out.println(out.toByteArray().length);
        log.info("[jdk方式======》end]");

        log.info("[json方式======》start]");
        System.out.println(Arrays.toString(JSONObject.toJSONString(person).getBytes()));
        System.out.println(JSONObject.toJSONString(person).getBytes().length);
        log.info("[json======》end]");
    }

    /**
     * 创建测试对象
     *
     * @return
     */
    private static Person create() {
        Person p = new Person();
        p.setAge(99);
        p.setPhoneNum("13156892351");
        p.setHeight(176.6);
        p.setSex(true);
        return p;
    }
}


由上图可知,jdk原生的序列化方式体积大,意味着占用的传输宽带更大。

使用protocol buffer测试
  • 创建message消息
syntax = "proto3";

option java_package = "com.gitee.asand.Person";
option java_outer_classname = "Person";

message Person {
  required string name = 1;
  required int32 age = 2;
  required string phoneNum = 3;
  required double height = 4;
  required bool sex = 5;
}

在此目录中创建Person.proto3


  • 编译
protoc --proto_path=src --java_out=build/gen src/foo.proto //官方例句

protoc --proto_path=C:\Users\peipe\Downloads\testproto --java_out=C:\Users\peipe\Downloads\testproto\out C:\Users\peipe\Downloads\testproto\Person.proto3

运行此命令,得到生成文件
把当前生成的文件拷贝到测试项目中

package com.gitee.asand;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Arrays;

@Slf4j
public class App {

    public static void main(String[] args) throws IOException {
        log.info("[测试jdk,json,protocolbuffer三种方式的优劣]");
        Person person = create();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(out);
        oos.writeObject(person);
        oos.flush();
        log.info("[jdk方式======》start]");
        System.out.println(Arrays.toString(out.toByteArray()));
        System.out.println(out.toByteArray().length);
        log.info("[jdk方式======》end]");

        log.info("[json方式======》start]");
        System.out.println(Arrays.toString(JSONObject.toJSONString(person).getBytes()));
        System.out.println(JSONObject.toJSONString(person).getBytes().length);
        log.info("[json======》end]");

        log.info("[protocolbuffer方式======》start]");
        PersonProto3.Person buildPerson = PersonProto3.Person.newBuilder()
                .setAge(person.getAge())
                .setName(person.getName())
                .setPhoneNum(person.getPhoneNum())
                .setSex(person.isSex())
                .setHeight(person.getHeight()).build();
        System.out.println(Arrays.toString(buildPerson.toByteArray()));
        System.out.println(buildPerson.toByteArray().length);
        log.info("[protocolbuffer方式======》end]");
    }

    /**
     * 创建测试对象
     *
     * @return
     */
    private static Person create() {
        Person p = new Person();
        p.setName("测试");
        p.setAge(99);
        p.setPhoneNum("13156892351");
        p.setHeight(176.6);
        p.setSex(true);
        return p;
    }
}


可以明显看到,protocolbuffer生成的体积很小,可知,在同样的宽带下,速度更快,如果数据量更大的话,差距更明显。

  • 反序列化
 log.info("[protocolbuffer方式======》start]");
        PersonProto3.Person buildPerson = PersonProto3.Person.newBuilder()
                .setAge(person.getAge())
                .setName(person.getName())
                .setPhoneNum(person.getPhoneNum())
                .setSex(person.isSex())
                .setHeight(person.getHeight()).build();
        byte[] content = buildPerson.toByteArray();
        System.out.println(Arrays.toString(content));
        System.out.println(content.length);
        log.info("[protocolbuffer方式======》end]");


        log.info("[protocol buffer 反序列化]");
        PersonProto3.Person person1 = PersonProto3.Person.parseFrom(content);
        System.out.println(person1);

RandomObject
粉丝 0
博文 122
码字总数 77655
作品 0
南岸
高级程序员
私信 提问
加载中
请先登录后再评论。
CDH5: 使用parcels配置lzo

一、Parcel 部署步骤 1 下载: 首先需要下载 Parcel。下载完成后,Parcel 将驻留在 Cloudera Manager 主机的本地目录中。 2 分配: Parcel 下载后,将分配到群集中的所有主机上并解压缩。 3 激...

cloud-coder
2014/07/01
6.9K
1
Go-node

Go-node 是一个用 Go 语言实现的 Erlang/OTP node 已支持的功能: Publish listen port via EPMD Handle incoming connection from other node using Erlang Distribution Protocol Spawn E......

匿名
2013/01/25
1.5K
1
django-c10k-demo

这是一个演示程序,用来实现同时 10000 个并发连接到 Django 。涉及的概念包括:the C10k problem, the WebSocket protocol, the Django web framework, and Python's upcoming asynchronou......

匿名
2013/03/27
1.7K
0
C++ 单元测试框架--cipra

cipra 是一个简单的、兼容 TAP (Test Anything Protocol) 的 C++ 单元测试框架。100% 使用标准的 C++11 编写,只提供一组头文件,可很方便的在你的 C++11 项目中使用。...

匿名
2013/04/17
1K
0
OpenOSPFD

OSPFD(Open Shortest Path First Protocol)路由协议的一个开源能实现,是OpenBGPD的姊妹项目。OpenOSPFD和OPENBGPD都是OPENBSD项目的一部分。OpenBSD项目介绍 OPENBSD...

匿名
2013/04/24
640
0

没有更多内容

加载失败,请刷新页面

加载更多

处理“ java.lang.OutOfMemoryError:PermGen空间”错误

问题: Recently I ran into this error in my web application: 最近,我在Web应用程序中遇到此错误: java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemoryError:PermGen空间......

技术盛宴
今天
7
0
从JS数组中删除重复的值[duplicate] - Remove duplicate values from JS array [duplicate]

问题: This question already has answers here : 这个问题已经在这里有了答案 : Get all unique values in a JavaScript array (remove duplicates) (79 answers) 获取JavaScript数组中的......

法国红酒甜
今天
11
0
如何使用AngularJS在浏览器的控制台中访问$ scope变量?

问题: I would like to access my $scope variable in Chrome's JavaScript console. 我想在Chrome的JavaScript控制台中访问$scope变量。 How do I do that? 我怎么做? I can neither see ......

fyin1314
今天
18
0
ImageMagick - 添加水印

背景 最近制作思维导图想添加自己的水印,网上很多例子都是使用ImageMagick来完成。但是不少代码在本地并不可行。经过一番试验,找到两个方法。 方法一 代码 stackoverflow方法改良: conver...

wffger
今天
11
0
OSChina 周四乱弹 —— 到底是怎样的饕餮盛宴在等待着我!

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 小小编辑推荐 :《你 能 來 保 護 我 的 世 界 嘛》- 歪门 《你 能 來 保 護 我 的 世 界 嘛》- 歪门 手机党少年们想听歌,请使劲儿戳(这里)...

小小编辑
今天
91
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部