俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

golang 使用 protobuf 的教程

 

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

4、运行如下命令

 

> go get -u github.com/golang/protobuf/protoc-gen-go
  • 简洁
  • 体积小:消息大小只需要XML的1/10 ~ 1/3
  • 速度快:解析速度比XML快20 ~ 100倍
  • 使用protobuf的编译器,可以生成更容易在编程中使用的数据访问代码

    更好的兼容性,protobuf设计的一个原则就是要能够很好的支持向下或向上兼容

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

(1)新建protobuf数据描述文件: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();
}

(3)从protobuf序列化文件中读取之前保存进去的数据。

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

完毕!示例代码详见:https://git.oschina.net/cchanghui/test-protobuf.git

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

3. 使用protobuf
新建一个空的maven项目,并添加protobuf运行时依赖:
pom.xml:

> protoc --go_out=. *.proto

(2)保存protobuf序列化数据到文件

//指定版本
//注意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;
}
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;
}

俄罗斯贵宾会 1

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();
        }

    }

}

5、在go语言中使用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);
    }

}

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加入环境变量。
    如果喜欢编译安装的,也可下载源码自行安装,最后将可执行文件加入环境变量。

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

 

cd D:protobufjava
mvn install(如果不想执行单元测试,可以执行:mvn install -Dmaven.test.skip=true)

本文由俄罗斯贵宾会发布于编程,转载请注明出处:golang 使用 protobuf 的教程

您可能还会对下面的文章感兴趣: