• protocol buffers的使用示例

    如果不了解protocol buffers,可以先参看:http://blog.csdn.net/zhu_xun/article/details/19343079

    本例的protobuf的版本为2.5.0,运行环境为windows平台(当然,在Linux下使用的方法也一样,只不过是使用shell脚本驱动protobuf程序的运行)

    下载protobuf运行环境包:可以到http://download.csdn.net/detail/u012875880/6931679下载。

    一、测试protobuf:

    1.先写个例子测试一下吧:

    在proto.exe所在的目录下新建一个.proto文件test.proto:

    里面的内容如下:

    1.package protobuf;
    2.option
    java_package = 
    "protobuf";
    3.option
    java_outer_classname = 
    "FirstExample";
    4.message
    testBuf  {
    5.required
    string name= 
    1;
    6.required
    int32 age = 
    2;
    7.}

    2.打开dos命令窗口

    3.进入protocbuf目录,本例中目录为C:UserszhkjDesktopprotoc-2.5.0-win32

    cd C:UserszhkjDesktopprotoc-2.5.0-win32

    4.运行protoc.exe程序生成数据访问类:

    protoc.exe --java_out=./ ./test.proto

    说明:java_out后的第一参数表示生成的数据访问类所在的目录,本例中为当前目录;第二个为proto文件的位置,本例中为当前目录下的test.proto文件。

    运行上述命令后,会发现在当前目录下生成了一个文件夹"protobuf":

    这是,进入刚生成的protobuf文件夹,会发现有个Java类:FirstExample.java

    至此,一个简单的测试就ok了。

    二、在eclipse工程中的使用说明

    1.新建一个Java工程"protobuf",工程目录结构如下:

    2.在lib目录下导入protobuf-java-2.5.0.jar、将protoc.exe拷贝至在protobuf工程跟目录下。

    3.在org.zhu.utils工具包里面新建一个可以自动生成数据访问类的工具类"GenerateClass.java",GenerateClass的内如下:

    01.package org.zhu.utils;
    02. 
    03.public class GenerateClass
    {
    04./**
    05.*
    调用protoc.exe生成java数据访问类
    06.*
    */
    07.public static void main(String[]
    args) 
    throws Exception
    {
    08.String
    protoFile = 
    "testFirstExample.proto";//如果要更换生成的数据访问类,只需在此进行更改
    09.//String
    protoFile = "person.proto";
    10.String
    strCmd = 
    "protoc.exe
    --java_out=./src ./proto/"
     +
    protoFile;
    11.Runtime.getRuntime().exec("cmd
    /c "
     + strCmd).waitFor();//通过执行cmd命令调用protoc.exe程序
    12. 
    13.}
    14.}

    4.在proto目录下新建.proto文件"person.proto",其中内容如下:

    01.package testProtobuf;//生成的数据访问类所在的包名(注意:在此无需写全包路径)
    02.option
    java_package = 
    "org.zhu.testProtobuf";//生成的数据访问类所在包的全路径
    03.option
    java_outer_classname = 
    "PersonProbuf";//生成的数据访问类的类名
    04.message
    Person {
    05.required
    string name = 
    1;//必须字段,在后面的使用中必须为该段设置值
    06.required
    int32 id = 
    2;//同上
    07.optional
    string email = 
    3;//可选字段,在后面的使用中可以自由决定是否为该字段设置值
    08. 
    09.enum PhoneType
    {
    //设置一个枚举类型
    10.MOBILE
    0;
    11.HOME
    1;
    12.WORK
    2;
    13.}
    14. 
    15.message
    PhoneNumber {
    16.required
    string number = 
    1;
    17.optional
    PhoneType type = 
    2 [default =
    HOME];
    18.}
    19. 
    20.repeated
    PhoneNumber phone = 
    4;//重复字段(可以认为是一个集合),在后面的使用中可以为该字段设置多个值
    21.}

    注:以上字段后面的"0","1","2"数字表示该条消息序列化时的字段编号即顺序

    5.运行GenerateClass.java程序生成数据访问类Person.java

    运行程序后,需刷新protobuf工程,这是你可以发现,在org,zhu,testProtobuf包下生成了一个PersonProtobuf.java类,参考如下:

    6.编写测试类:

    在org.zhu.test包下新建测试类TestPersonProbuf.java,内容如下:

    01./**
    02.*
    测试PersonProbuf.java
    03.*
    */
    04.public class TestPersonProbuf
    {
    05. 
    06./**
    07.*
    @param args
    08.*
    @throws Exception
    09.*/
    10.public static void main(String[]
    args) 
    throws Exception
    {
    11.//
    序列化过程
    12.//
    PersonProtobuf是生成的数据访问类的名字,即proto文件中的java_outer_classname
    13.//
    Person是里面某个消息序列的名字,即proto文件中的message Person
    14.PersonProtobuf.Person.Builder
    builder = PersonProtobuf.Person.newBuilder();
    15.//设置消息序列中的字段值
    16.builder.setEmail("zhuxun777@gmail.com");
    17.builder.setId(320324);
    18.builder.setName("Jack
    Zhu"
    );
    19.//phone字段在person.proto文件中被定义为repeated型,可以放多个值
    20.//(在本例中,phone字段的数据类型为消息类型PhoneNumber)
    21.builder.addPhone(PersonProtobuf.Person.PhoneNumber.newBuilder().setNumber("18762678793").setType(Person.PhoneType.HOME));
    22.builder.addPhone(PersonProtobuf.Person.PhoneNumber.newBuilder().setNumber("18651581021").setType(Person.PhoneType.HOME));
    23. 
    24.Person
    person = builder.build();
    25.byte[]
    buf = person.toByteArray();
    26. 
    27.//把序列化后的数据写入本地磁盘
    28.ByteArrayInputStream
    stream = 
    new ByteArrayInputStream(buf);
    29.BufferedOutputStream
    bos = 
    new BufferedOutputStream(new FileOutputStream("F:/protobuf.txt"));//设置输出路径
    30.BufferedInputStream
    bis = 
    new BufferedInputStream(stream);
    31.int b
    = -
    1;
    32.while ((b
    = bis.read()) != -
    1)
    {
    33.bos.write(b);
    34.}
    35.bis.close();
    36.bos.close();
    37. 
    38. 
    39.//读取序列化后的数据
    40.try {
    41.Person
    person01 = PersonProtobuf.Person.parseFrom(buf);
    42.List<PhoneNumber>
    phones = person01.getPhoneList();
    43.String
    strPhone = 
    "";
    44.for(PhoneNumber
    phone : phones){
    45.strPhone
    += phone.getNumber() + 
    "  
    "
    ;
    46.}
    47.//String
    strResult = person01.getName() + "," + person01.getId() + "," + person01.getEmail() + "," + strPhone;
    48.//System.out.println(strResult);
    49.catch (InvalidProtocolBufferException
    e) {
    50.e.printStackTrace();
    51.}
    52. 
    53.//读取序列化后写入磁盘的数据
    54.try {
    55.BufferedInputStream
    bis2 = 
    new BufferedInputStream(new FileInputStream("F:/protobuf.txt"));
    56.byte b2
    = -
    1;
    57.List<Byte>
    list = 
    new LinkedList<Byte>();
    58.while ((b2
    = (
    byte)
    bis2.read()) != -
    1)
    {
    59.list.add(b2);
    60.}
    61.bis2.close();
    62.int length
    = list.size();
    63.byte[]
    byt = 
    new byte[length];
    64.for(int i
    0;
    i < length; i++){
    65.byt[i]
    = list.get(i);
    66.}
    67.Person
    person01 = PersonProtobuf.Person.parseFrom(byt);
    68.List<PhoneNumber>
    phones = person01.getPhoneList();
    69.String
    strPhone = 
    "";
    70.for(PhoneNumber
    phone : phones){
    71.strPhone
    += phone.getNumber() + 
    "  
    "
    ;
    72.}
    73.String
    strResult = person01.getName() + 
    "," +
    person01.getId() + 
    "," +
    person01.getEmail() + 
    "," +
    strPhone;
    74.System.out.println(strResult);
    75.catch (InvalidProtocolBufferException
    e) {
    76.e.printStackTrace();
    77.}
    78.}
    79. 
    80.}

    以上演示了把信息通过protobuf序列化后写入磁盘,以及从磁盘读取后反序列化的过程。protobuf把信息写入磁盘后,文件的大小为69字节,而用json表示大概有90多字节,用xml表示大概需150字节(在去掉xml换行及空格的情况下),用此可见protobuf的威力了。当然,protobuf除了占用空间小外,还有速度快,使用简单等诸多优点。

    参考本示例工程代码http://www.it165.net/uploadfile/files/2014/0218/protobuf.zip

    更详尽的使用说明请参看官方文档;https://developers.google.com/protocol-buffers/docs/javatutorial

protocol buffers的使用示例的更多相关文章

  1. protocol buffers的使用示例[z]

    [http://blog.csdn.net/zhu_xun/article/details/19397081] protocol buffers的使用示例 如果不了解protocol buffers, ...

  2. Protocol buffers 介绍

    Protocol buffers和mxl一样在序列化数据结构时很灵活.高效和智能,但是它的优势在于定义文件更小,读取速度更快,使用更加简单.目前protocol buffers支持C++.java和p ...

  3. Protocol Buffers(Protobuf) 官方文档--Protobuf语言指南

    Protocol Buffers(Protobuf) 官方文档--Protobuf语言指南 约定:为方便书写,ProtocolBuffers在下文中将已Protobuf代替. 本指南将向您描述如何使用 ...

  4. Protocol Buffers(Protobuf)开发者指南---概览

    Protocol Buffers(Protobuf)开发者指南---概览 欢迎来到protocol buffers的开发者指南文档,protocol buffers是一个与编程语言无关‘.系统平台无关 ...

  5. Protocol Buffers编码详解,例子,图解

    Protocol Buffers编码详解,例子,图解 本文不是让你掌握protobuf的使用,而是以超级细致的例子的方式分析protobuf的编码设计.通过此文你可以了解protobuf的数据压缩能力 ...

  6. 详解PROTOCOL BUFFERS

    1. 前言 Protocal Buffers是google推出的一种序列化协议.由于它的编码和解码的速度,已经编码后的大小控制的较好,因此它常常被用在RPC调用中,传递参数和结果.比如gRPC. Pr ...

  7. Protocol Buffers简明教程

    随着微服务架构的流行,RPC框架渐渐地成为服务框架的一个重要部分. 在很多RPC的设计中,都采用了高性能的编解码技术,Protocol Buffers就属于其中的佼佼者. Protocol Buffe ...

  8. Google Protocol Buffers 入门

    Google Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化.它很适合做数据存储或 RPC 数据交换格式.可用于通讯协议.数据存储等领域的 ...

  9. protobuf Protocol Buffers 简介 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

随机推荐

  1. Git_学习_09_Commit message 和 Change log 编写指南

    一.前言 二.Commit message编写 1.规范 2.用空行分开主题和正文 提交时只执行 git commit,这时就会跳出文本编辑器,让你写多行. git commit 主题和正文分开 每次 ...

  2. LeetCode OJ:Binary Tree Level Order Traversal(二叉树的层序遍历)

    Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...

  3. IO编程、操作文件或目录、序列化、JSON

    IO中指Input/Output,即输入和输出:涉及到数据交换的地方,通常是磁盘.网络等,就需要IO接口 1.由于CPU和内存的速度远远高于外设的速度,所以,在IO编程中,存在速度严重不匹配问题.eg ...

  4. (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令

    (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一节:(C#)Windows Shell 外壳编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单 上一节说到如 ...

  5. QT:QString、QByteArray和char *的转换 【转载】

    原文网址:http://blog.csdn.net/light1028/article/details/7899541 第一种,数据流的方式,这里只说从QByteArray转向QString. QBy ...

  6. bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...

  7. 在系统学习javaEE开发的颠覆者Springboot时遇到的localhost无法访问的问题

    就是新建了一个Springboot项目,但是无法正常访问. 关闭防火墙试了,mvn方式启动试了,换端口试了.然后用Tomcat的start.bat测试发现localhost是可以访问的. 上网找到各种 ...

  8. MYSQLdump参数详解(转)

    mysqldump客户端可用来转储数据库或搜集数据库进行备份或将数据转移到另一个SQL服务器(不一定是一个MySQL服务器).转储包含创建表和/或装载表的SQL语句. 如果你在服务器上进行备份,并且表 ...

  9. hihoCoder#1139(二分+bfs)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回和上上回里我们知道Nettle在玩<艦これ>,Nettle在整理好舰队之后终于准备出海捞船和敌军交战了 ...

  10. vijos1264:神秘的咒语

    描述 身为拜月教的高级间谍,你的任务总是逼迫你出生入死.比如这一次,拜月教主就派你跟踪赵灵儿一行,潜入试炼窟底. 据说试炼窟底藏着五行法术的最高法术:风神,雷神,雪妖,火神,山神的咒语.为了习得这些法 ...