protoBuf的簡單使用

時間:2019.12.16:22:25

環境需求

下載proto包:地址 提取碼:51j8
下載之後,將解壓後的bin目錄設置到系統變量
然後 cmd 打開測試 protoc --version 查看版本,顯示爲 libproto 3.7.0即安裝好

使用proto生成java文件

新建proto文件如下

syntax = "proto3"; //表示建立的版本,默認爲2

message Prop {
     string key = 1;
     string value = 2;
}
message GeoData {
    bytes geometry = 1;
    repeated Prop prop = 2;
}

我的示例proto文件需要的字段1:bytes(必須有),字段2:Prop(可重複可有多個),而Prop又包含了兩個必須的屬性(key&&value)
在本機運行`以下代碼,將會根據寫好的proto文件 java 文件到 E:\java 目錄下,將其複製到java項目中

protoc --java_out=E:\java person.proto

根據編寫的proto文件名爲 GeoDataOuterClass

java示例代碼

需要依賴

    //protobuf  
    compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.11.1'
    compile group: 'com.google.protobuf', name: 'protobuf-java-util', version: '3.11.1'

以下代碼爲根據定義字段序列化proto文件和反序列化

package com.atlchain.bcgis.data.protoBuf;

import com.alibaba.fastjson.JSONObject;
import com.atlchain.bcgis.data.Utils;
import com.google.protobuf.ByteString;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.ParseException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
 * 數據與 proto 的序列化和反序列化
 */
public class protoConvert {

    /**
     * 序列化數據
     * @param geometry      空間幾何數據
     * @param jsonObject    屬性信息
     * @return
     */
    public static byte[] dataToProto(Geometry geometry, JSONObject jsonObject){

		//放入定義好的 bytes
        byte[] bytes = Utils.getBytesFromGeometry(geometry);
        ByteString geometryByte = ByteString.copyFrom(bytes);//proto中沒有bytes,只有ByteString
        GeoDataOuterClass.GeoData.Builder protoBuilder = GeoDataOuterClass.GeoData.newBuilder();
        protoBuilder.setGeometry(geometryByte);
        //放入JSONObject,其中在以key value的形式放入
        Set<String> keys =  jsonObject.keySet();
        for(String key : keys){
            GeoDataOuterClass.Prop.Builder prop = GeoDataOuterClass.Prop.newBuilder();
            prop.setKey(key);
            prop.setValue(jsonObject.get(key).toString());
            protoBuilder.addProp(prop);
        }
        GeoDataOuterClass.GeoData outData = protoBuilder.build();
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            outData.writeTo(output);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] byteArray = output.toByteArray();
        return byteArray;
    }

    /**
     * 反序列化得到 geometry
     * @param byteArray
     * @return
     */
    public static Geometry getGeometryFromProto(byte[] byteArray){
        GeoDataOuterClass.GeoData protoBuilder = parsingProto(byteArray);
        ByteString byteString = protoBuilder.getGeometry();
        byte[] geometryBytes = byteString.toByteArray();
        Geometry geometry = null;
        try {
            geometry = Utils.getGeometryFromBytes(geometryBytes);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return geometry;
    }

    /**
     * 反序列化得到屬性
     * @param byteArray
     * @return
     */
    public static JSONObject getPropFromProto(byte[] byteArray){
        GeoDataOuterClass.GeoData protoBuilder = parsingProto(byteArray);
        List<GeoDataOuterClass.Prop> list = protoBuilder.getPropList();
        JSONObject jsonObject = new JSONObject();
        for(int i = 0; i < list.size(); i++){
            String key = list.get(i).getKey();
            String value = list.get(i).getValue();
            jsonObject.put(key, value);
        }
        return jsonObject;
    }

    private static GeoDataOuterClass.GeoData parsingProto(byte[] byteArray){
        ByteArrayInputStream input = new ByteArrayInputStream(byteArray);
        GeoDataOuterClass.GeoData protoBuilder = null;
        try {
            protoBuilder = GeoDataOuterClass.GeoData.parseFrom(input);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return protoBuilder;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章