protobuf使用简介

By admin in 4858.com on 2019年4月10日

一、下载protobuf的编写翻译器protoc

官网:
4858.com 1

json与protobuf做多少传输比较:
json用起来确实很有益。但针锋相对于protobuf数据量更加大些。做贰个移动端应用,为用户省点流量照旧很有不可缺少的。正好也能够学习一下protobuf的行使

Protocol
Buffers是一种跨语言、跨平台用于连串化、反体系化结构数据的可扩张机制工具集。这里首要记录一下Java语言的运用。

地址:

环境:windows,java

0、跟Json相比较,protobuf 的利害:

优点:

  • 品质更加高,越发正式;
  • 编解码速度快,数据体量小;
  • 使用统壹的正统,不用再担心大小写差异造成解析战败等题材。

缺点:

  • 失去了部分便利性;
  • 变动协议字段,需求再行生成文书;
  • 数码尚未可读性;

一、下载

      首先下载protocol
buffers,使用Java语言,下载Java版本protobuf-java-版本号.zip,接下来再下载对应版本的compiler,大家是Windows平台,下载protoc-版本号-win32.zip。

      ☆.注意,下载的protobuf-java的本子号一定要和compiler版本一致

https://github.com/google/protobuf/releases

1. protobuf概述
protobuf是谷歌(Google)开发壹种数码描述格式,能够将结构化数量体系化,可用于数码存款和储蓄通信协议等方面。
protobuf是以二进制来存款和储蓄数据的。相对于JSON和XML具有以下优点:

1、安装protobuf库文件

方法(1)使用go get

go get github.com/golang/protobuf/proto(待验证)

方法(二)下载文件
依然直接通过protobuf下载链接,戳那里上下载或git
clone下来对应放到到 $GOPATH\src\golang.org\x\protobuf 中(可用)

二、编译jar包配置

     
一>.比如,笔者下载了protobuf-java-三.一.0.zip和protoc-三.1.0-win3贰.zip,把它们解压到均等目录E:\protobuf,目录分别为E:\protobuf\protobuf-3.1.0和E:\protobuf\protoc-3.1.0-win32

     
在E:\protobuf\protoc-3.一.0-win3第22中学找到protoc.exe,在path里安插它的环境变量,并在指令行里执行”protoc
–version”,能健康实施,并出示版本号,表示配置成功

4858.com 2

protoc

         
 二>.因为protobuf是应用maven编写翻译,借使未有配备maven环境,须求先下载Maven,并布署环境变量。在命令行执行“mvn
–version ”,符合规律突显版本号,表示配置成功。

4858.com 3

mvn

             3>.这一步很关键

protobuf使用简介。                   
①、把protoc.exe复制到E:\protobuf\protobuf-3.1.0\src 目录下

                   
2、在cmd命令行窗口,cd重平昔到“E:\protobuf\protobuf-3.1.0\java”目录,然后实施”mvn
package”,编译jar文件,假设未有出错,会在”E:\runtime\protobuf-3.1.0\java\core“目录    
 下生成”\target”文本夹,编写翻译的jar文件就在此目录下

4858.com 4

jar

https://developers.google.com/protocol-buffers/

–下载链接

https://github.com/google/protobuf/releases

–编译jar参考

http://blog.csdn.net/u013656135/article/details/52194248

window:
    下载: protoc-3.3.0-win32.zip
   
解压,把bin目录下的protoc.exe复制到GOPATH/bin下,GOPATH/bin插手环境变量。
    当然也可放在其他目录,需加入环境变量,能让系统找到protoc.exe
linux:
    下载:protoc-3.3.0-linux-x86_64.zip 或
protoc-3.3.0-linux-x86_32.zip
   
解压,把bin目录下的protoc复制到GOPATH/bin下,GOPATH/bin插手环境变量。
   
假使喜欢编写翻译安装的,也可下载源码自行设置,最终将可执行文件参加环境变量。

  • 简洁
  • 体量小:音信大小只须要XML的一成 ~ 1/3
  • 进程快:解析速度比XML快20 ~ 100倍
  • 选拔protobuf的编写翻译器,能够转变更易于在编程中使用的数量访问代码

    越来越好的包容性,protobuf设计的三个原则就是要力所能及很好的支撑向下或进步包容

二、protobuf的编写翻译器protoc

在protoc下载链接,戳那里上找到protoc的裁减包下载。并置于$GOROOT的bin目录下。

2、获取protobuf的编写翻译器插件protoc-gen-go
    进入GOPATH目录
    运行

2. 下载,安装
在利用protobuf此前,供给安装protobuf编写翻译器和运作时环境。
出于protobuf是跨平台,跨语言的,所以必要下载和设置相应版本的编写翻译器和周转时重视。

三、protobuf的编写翻译器protoc

在go中使用protobuf,有多个可选拔的包goprotobuf(go官方出品)和gogoprotobuf(二选1即可)。
gogoprotobuf完全同盟google
protobuf,它生成的代码质量和编解码质量均比goprotobuf高1些。
使用protobuf:

go get github.com/golang/protobuf/protoc-gen-go

使用gogoprotobuf:(待验证)
gogoprotobuf有多个插件能够使用(2选壹即可):

  • protoc-gen-gogo:和protoc-gen-go生成的公文大致,质量也大致如出1辙(稍微快一丝丝)
  • protoc-gen-gofast:生成的文件更复杂,品质也越来越高(快5-七倍)

//gogo
go get github.com/gogo/protobuf/protoc-gen-gogo
//gofast
go get github.com/gogo/protobuf/protoc-gen-gofast
//安装gogoprotobuf库文件
go get github.com/gogo/protobuf/proto
go get github.com/gogo/protobuf/gogoproto //那个不装也没涉及
//生成编写翻译文件
//gogo
protoc –gogo_out=. *.proto
//gofast
protoc –gofast_out=. *.proto

中标后会在GOPATH的率先个目录的bin文件夹下生成protoc-gen-go可执行文书(假若该路线没在系统的环境变量中,则需求将改路径也参与到环境变量的path中去)。

> go get -u github.com/golang/protobuf/protoc-gen-go

(1)protobuf编写翻译器下载:。
对于windows平台,下载:protoc-${version}-win32.zip。在此以protoc-3.3.0-win32.zip为例。
解压到钦定目录,如:D:\protoc-三.三.0-win3二。添加到windows环境变量:D:\protoc-3.3.0-win32\bin。

4、使用protoc编译.proto文件成.pd.go文件

命令行进入.proto文件所在路径,使用 命令:

protoc –go_out=. *.proto

会把.pd.go文件生成到当前目录下,即成功编写翻译过程。

    假如成功,会在GOPATH/bin下生成protoc-gen-go.exe文件

(2)protobuf运营时下载:protobuf运营时环境是分别不一样语言的,针对区别语言的设置情势各异。
下载protobuf到钦命目录:git clone

对此java语言而言,能够经过maven将protobuf运营时重视安装到本地仓库,详见:。
要求小心的是,在履行:mvn install
以前,要求将protobuf编写翻译器(在此即:D:\protoc-3.3.0-win32\4858.com,bin\protoc.exe)拷贝到protobuf目录下的src路径下,即:D:\protobuf\src。
要不然,在编写翻译安装protobuf运行时环境时报错:

 

Execute failed: java.io.IOException: Cannot run program ...

三、创制1个test.proto文件

cd D:\protobuf\java
mvn install(假若不想实行单元测试,能够实施:mvn install
-Dmaven.test.skip=true)

//指定版本
//注意proto3与proto2的写法有些不同
syntax = "proto3";

//包名,通过protoc生成时go文件时
package test;

//手机类型
//枚举类型第一个字段必须为0
enum PhoneType {
    HOME = 0;
    WORK = 1;
}

//手机
message Phone {
    PhoneType type = 1;
    string number = 2;
}

//人
message Person {
    //后面的数字表示标识号
    int32 id = 1;
    string name = 2;
    //repeated表示可重复
    //可以有多个手机
    repeated Phone phones = 3;
}

//联系簿
message ContactBook {
    repeated Person persons = 1;
}

将在maven本地仓库安装protobuf运营时重视jar包(注意:下载protobuf编译器和周转时环境的本子要保持壹致!在此下载的是流行版本:三.三.0),包涵:

 

  • protobuf-java: The core Java Protocol Buffers library. Most users only
    need this artifact.
  • protobuf-lite: The lite version of core Java Protobuf Buffers library.
    It is a subset of the core library and is used together with the ‘lite’
    code generator flag to reduce generated code size for mobile.
  • protobuf-java-util: Utilities to work with protos. It contains JSON
    support as well as utilities to work with proto3 well-known types.

肆、运营如下命令

3. 使用protobuf
新建三个空的maven项目,并丰盛protobuf运营时依赖:
pom.xml:

> protoc --go_out=. *.proto
<dependencies>
    <!-- 添加protobuf运行时依赖 -->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.3.0</version>
    </dependency>
</dependencies>

会生成一个test.pb.go的文本,具体的文本内容作者就不截图了。

(一)新建protobuf数据描述文件:addressbook.proto

 

syntax = "proto2";

package tutorial;

option java_package = "org.chench.test.protobuf";
option java_outer_classname = "AddressBookProtos";

message Person {
    required string name = 1;
    required int32 id = 2;
    optional string email = 3;

    enum PhoneType {
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
    }

    message PhoneNumber {
        required string number = 1;
        optional PhoneType type = 2 [default = HOME];
    }

    repeated PhoneNumber phones = 4;
}

message AddressBook {
    repeated Person people = 1;
}

伍、在go语言中行使protobuf

编写翻译addressbook.proto,在windows控制台进入addressbook.proto文件所在目录路径下,执行如下编译操作:

package main;

import (
 "github.com/golang/protobuf/proto"
 "protobuf/test"
 "io/ioutil"
 "os"
 "fmt"
)

func write() {
 p1 := &test.Person{
  Id:   1,
  Name: "小张",
  Phones: []*test.Phone{
   {test.PhoneType_HOME, "111111111"},
   {test.PhoneType_WORK, "222222222"},
  },
 };
 p2 := &test.Person{
  Id:   2,
  Name: "小王",
  Phones: []*test.Phone{
   {test.PhoneType_HOME, "333333333"},
   {test.PhoneType_WORK, "444444444"},
  },
 };

 //创建地址簿
 book := &test.ContactBook{};
 book.Persons = append(book.Persons, p1);
 book.Persons = append(book.Persons, p2);

 //编码数据
 data, _ := proto.Marshal(book);
 //把数据写入文件
 ioutil.WriteFile("./test.txt", data, os.ModePerm);
}

func read() {
 //读取文件数据
 data, _ := ioutil.ReadFile("./test.txt");
 book := &test.ContactBook{};
 //解码数据
 proto.Unmarshal(data, book);
 for _, v := range book.Persons {
  fmt.Println(v.Id, v.Name);
  for _, vv := range v.Phones {
   fmt.Println(vv.Type, vv.Number);
  }
 }
}

func main() {
 write();
 read();
}
protoc -I=. --java_out=. ./addressbook.proto

4858.com 5

生成java
class:org.chench.test.protobuf.AddressBookProtos.java,将转变的java文件拷贝到前边新建的maven项目中。

(二)保存protobuf系列化数据到文件

package org.chench.test.protobuf;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;

import org.chench.test.protobuf.AddressBookProtos.AddressBook;
import org.chench.test.protobuf.AddressBookProtos.Person;
import org.chench.test.protobuf.AddressBookProtos.Person.PhoneNumber;
import org.chench.test.protobuf.AddressBookProtos.Person.PhoneType;

/**
 * 使用protobuf类示例: <br />
 * 从控制台输入相关信息,然后将数据序列化到文件。
 * @desc org.chench.test.protobuf.AddPerson
 * @author chench9@lenovo.com
 * @date 2017年6月7日
 */
public class AddPerson {

    static Person PromptForAddress(BufferedReader stdin,
            PrintStream stdout) throws IOException {
        Person.Builder person = Person.newBuilder();

        stdout.print("Enter person ID: ");
        person.setId(Integer.valueOf(stdin.readLine()));

        stdout.print("Enter name: ");
        person.setName(stdin.readLine());

        stdout.print("Enter email address (blank for none): ");
        String email = stdin.readLine();
        if(email.length() > 0) {
            person.setEmail(email);
        }

        while(true) {
            stdout.print("Enter a phone number (or leave blank to finish): ");

            String number = stdin.readLine();
            if(number.length() == 0) {
                break;
            }

            PhoneNumber.Builder phoneNumber = PhoneNumber.newBuilder();
            phoneNumber.setNumber(number);

            stdout.print("Is this a mobile, home, or work phone? ");
            String type = stdin.readLine();
            if("mobile".equalsIgnoreCase(type)) {
                phoneNumber.setType(PhoneType.MOBILE);
            }else if("home".equalsIgnoreCase(type)) {
                phoneNumber.setType(PhoneType.HOME);
            }else if("work".equalsIgnoreCase(type)) {
                phoneNumber.setType(PhoneType.WORK);
            }

            person.addPhones(phoneNumber);
        }

        return person.build();
    }

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.err.println("Usage:  AddPerson ADDRESS_BOOK_FILE");
            System.exit(-1);
        }

        AddressBook.Builder addressBook = AddressBook.newBuilder();
        try {
            // 从指定文件读取数据
            addressBook.mergeFrom(new FileInputStream(args[0]));
        } catch (FileNotFoundException e) {
            System.out.println(args[0] + ": File not found.  Creating a new file.");
            e.printStackTrace();
        }

        addressBook.addPeople(PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
                System.out));

        FileOutputStream out = new FileOutputStream(args[0]);
        addressBook.build().writeTo(out);
    }

}

(三)从protobuf体系化文件中读取在此之前封存进去的数码。

package org.chench.test.protobuf;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.chench.test.protobuf.AddressBookProtos.AddressBook;
import org.chench.test.protobuf.AddressBookProtos.Person;
import org.chench.test.protobuf.AddressBookProtos.Person.PhoneNumber;

/**
 * 从protobuf序列化文件读取数据。
 * @desc org.chench.test.protobuf.ListPeople
 * @author chench9@lenovo.com
 * @date 2017年6月7日
 */
public class ListPeople {

    static void Print(AddressBook addressBook) {
        for(Person p : addressBook.getPeopleList()) {
            System.out.println("Person ID: " + p.getId());
            System.out.println("  Name: " + p.getName());
            if (p.hasEmail()) {
                System.out.println("  E-mail address: " + p.getEmail());
            }

            for(PhoneNumber pn : p.getPhonesList()) {
                switch (pn.getType()) {
                    case MOBILE:
                        System.out.print("  Mobile phone #: ");
                        break;
                    case HOME:
                        System.out.print("  Home phone #: ");
                        break;
                    case WORK:
                        System.out.print("  Work phone #: ");
                        break;
                }
                System.out.println(pn.getNumber());
            }
        }
    }

    /**
     * @param args
     * @throws IOException 
     * @throws FileNotFoundException 
     */
    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.err.println("Usage:  ListPeople ADDRESS_BOOK_FILE");
            System.exit(-1);
        }

        try {
            AddressBook addressBook = AddressBook.parseFrom(new FileInputStream(args[0]));
            Print(addressBook);
        } catch (FileNotFoundException e) {
            System.out.println(args[0] + ": File not exists");
            e.printStackTrace();
        }

    }

}

得了!示例代码详见:

【参考】

protobuf简单使用

protobuf官方手册

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有