zoukankan      html  css  js  c++  java
  • Protocol Buffer序列化/反序列化---初体验(java版)

    今天闲遐时学习了

    Protocol Buffer

    在网上看到了许多资料,其中不泛精品,想要详细了解的请看文章结尾的友情链接,我这里就做加深印象,快速入门的一个完整的demo,仅此而已.

    学完你可以得到什么:

    1. 可以使用protoc工具序列化类,反序列化类
    2. 基于java语言的对protoc工具的基本使用
    3. 基本protoc的基础api使用

    首先我们需要下载官方的编译工具,

    FQ版: 官方文档

    不翻版:我的仓库

    整体流程:序列化一个实体类,在反序列出来得到结果:

    先放出结果来瞅瞅:

    可以看到数据压缩了将近一半多,so GOOD!!!

    言归正传:

    首先我们

     新建一个proto文件,定义基本的数据格式

    syntax = "proto2";
    
    option java_outer_classname="PersonProtoBuf";
    
    message Person{
    	optional int32 id = 1;
    	optional int32 age = 2;
    	optional string name= 3;
    	optional  bool is_sex= 4;
    }
    message Class{
    	optional int32 grade_num = 1;
    	optional int32 class_num = 2;
    	optional Person head_teacher = 3;	
    	repeated Person students = 4[packed=true];
    }
    * 第一句确定是语法版本
    * 其二是指定生成的class
    * 还可以指定包名
    * 主体:
    *  message Person{...}
    *  主要实体编写区域
    *  其中:
    *      optional:非必需参数
    *      repeated:可以重复存储一个字段,其中是待顺序的存取
    *      required:必要参数
    *
    *      结构体、类,统一定义为 message,实际上是嵌套类
    *
    *      int32,string,bool 数据格式
    *      1,2,3,4 表示数据元素的唯一编号
    *
    *
    * 还可以定义:
    *  enum xx          //枚举定义
    *     {
    *         XXX = 0;
    *         ...
    *     }
    *
    *  struct SS{           //结构体定义
    *         required int s1;
    *         required int s2;
    *     }
    *
    * 具体需要FQ查看官网文档: https://developers.google.com/protocol-buffers/docs/javatutorial
    * 接下来就需要:使用java程序进行压缩,模拟解压.
    这个protoc的工具加不加环境变量随便,使用命令(我这里是加了环境变量):
    protoc --java_out=./ ./****.proto文件
    其中第一个./是将生成的java文件放在本目录下,其二个则是在找到这个proto文件,
    这里还需要编写其proto文件...

     执行结果:

    我们现在创建java项目,添加protocol 的jar依赖

            <dependency>
                <groupId>com.google.protobuf</groupId>
                <artifactId>protobuf-java</artifactId>
                <version>3.7.0-rc1</version>
            </dependency>
    

      基本结构

    public class ServiceSchool {
    
    
        private PClass pClass = null;
    
        /**
         * 初始化班级
         */
        @Before
        public void initClass(){
            //设置教师类
            Person teacher = new Teacher(1,30,"王老师",false);
    
            //设置学生类 一个班级50人
            List<Person> allStudents = new ArrayList<>();
            for(int i = 0; i < 50; i++) {
                Person student = null;
                if(i % 2 == 0) {
                    student = new Student(i + 1000, (int) (Math.random() * 20), "学生" + i + "号", true);
                }else{
                    student = new Student(i + 1000, (int) (Math.random() * 20), "学生" + i + "号", false);
                }
                allStudents.add(student);
            }
            pClass = new PClass(7,3,teacher,allStudents);
        }
    
        /**
         * 模拟传输的数据字节数组
         */
        private byte[] pipeByArray = null;
    
        /**
         * 压缩
         */
        @Test
        public void compression() throws InvalidProtocolBufferException {
    //        原数据
            System.out.println("原数据的长度: "+pClass.toString().length());
            //压缩后
            School.Class.Builder pClassCom = setBuilder(pClass);
            School.Class build = pClassCom.build();
            pipeByArray = build.toByteArray();
            System.out.println("压缩后数据长度:"+pipeByArray.length);
        }
    
        /**
         * 模拟解压
         */
        @After
        public void decompression() throws InvalidProtocolBufferException {
            School.Class.Builder aClass = School.Class.parseFrom(pipeByArray).toBuilder();
    ////        解压
            int classNum = aClass.getClassNum();
            int gradeNum = aClass.getGradeNum();
            School.Person headTeacher = aClass.getHeadTeacher();
            List<School.Person> studentsList = aClass.getStudentsList();
            System.out.println("教师:"+headTeacher.getId()
                    +headTeacher.getName()
                    +headTeacher.getAge()
                    +headTeacher.getIsSex());
            for(School.Person p : studentsList){
                System.out.println(p.getName()+"-"+p.getId()+"-"+p.getIsSex()+"-"+p.getAge());
            }
        }
    
        /**
         * 添加数据
         *
         * @param pClass
         * @return
         */
        private School.Class.Builder setBuilder(PClass pClass){
            School.Person.Builder person = School.Person.newBuilder();
            //教师类
            Person headTeacher = pClass.getHeadTeacher();
            //添加教师类
            person.setName(headTeacher.getName());
            person.setAge(headTeacher.getAge());
            person.setIsSex(headTeacher.isSex());
            person.setId(headTeacher.getId());
            //教室类
            School.Class.Builder sClass = School.Class.newBuilder();
            sClass.setGradeNum(pClass.getGradeNum());
            sClass.setClassNum(pClass.getClassNum());
            sClass.setHeadTeacher(person);
    
            //遍历学生
            for(int i = 0; i < pClass.getStudents().size();i++){
                Person p = pClass.getStudents().get(i);
                person.setName(p.getName());
                person.setAge(p.getAge());
                person.setIsSex(p.isSex());
                person.setId(p.getId());
                sClass.addStudents(i,person);
            }
    
            return sClass;
        }
    }
    

      

    发现其中数据量越少,压缩后会更小基本上都是1/3原来的体积,下一次准备使用这个协议做rpc了,哈哈

    参考网站:

    https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
    https://worktile.com/tech/share/prototol-buffers

    平凡是我的一个标签
  • 相关阅读:
    用OSCache进行缓存对象
    oscache的使用
    WHM(Web Hosting Manager)/CPANEL 设置及linux 文件权限 经验
    辗转相除法求最大公约数和最小公倍数【gcd】
    u6填写入库单单据报错
    账表名称无法显示
    商贸通反利怎么计算
    UFO报表转换不成功!请检查文件版本或使用DOS文件转换工具
    备份计划不执行
    821升级U6报错
  • 原文地址:https://www.cnblogs.com/guyanzy/p/10432430.html
Copyright © 2011-2022 走看看