nodejs解析protobuf文件

一、protobuf介绍:

1. 什么是protbuf

是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

2. protobuf语法
syntax = "proto2";          // PB协议版本
import "Common.proto";      // 引入Common.proto,位于Protobuf sdk中

message PayInfo{
	required string payid = 1;             // 支付相关的字段信息
	optional string goodinfo = 2;          // optional 为可选参数
	required string prepayid = 3;          // required为必填参数
	optional string mode = 4;
	optional int  userid = 5;
	repeated string  extra = 6;           // repeated 为数组
}

二、如何使用nodejs解析protobuf生成的二进制文件:

1. 下载第三方库protobufjs

npm install protobufjs

2. 编译对应的protobuf文件成json

网上很多教程都是 pbjs *.proto -t json > *.json
这样是执行不了的,除非你把pbjs加到环境变量中去

我们可以选择你的工作目录在
ln -s ./node_modules/protobufjs/bin/pbjs pbjs
创建一个软链接

执行 ./pbjs proto文件的路径 -t -json > 生成的json文件路径和名称(自己起)

编译的时候注意的地方是,不需要把所有依赖的proto文件都编译,只需要把最上层的proto文件编为json文件即可

3.解析对应的二进制protobuf文件

废话不多说直接上代码

var protobuf = require("./node_modules/protobufjs");
var fs = require('fs');
var jsonDescriptor = require("./map.json"); // exemplary for node

var jsonCrosswalk = require("./json/map_crosswalk.json")

var root = protobuf.Root.fromJSON(jsonDescriptor);

var hdmap = root.lookupType("adu.common.hdmap.Map");

var data = fs.readFileSync('./base_map.bin');

message = hdmap.decode(data);
//这一步很重要,只有把decode出来的字符串,转换成一个对象之后才能取到变量
var object = hdmap.toObject(message, {
		bool:Boolean,
        longs: Number,
        enums: Number ,
        bytes: String,
		Object:String
        // see ConversionOptions
    });

//遍历对应的元素,可以对照对应的proto文件解析,这块crosswalk是一个数组对象,v中的polygon是一个基本的对象,里面的元素都是基本类型
object.crosswalk.forEach(function(v,i,a){
	console.log(v.polygon);
});

//version元素是string类型,在object对象中表现是一个base64的串,需要解码为字符串
var version =object.header.version
var b = new Buffer.from(version, 'base64')
var s = b.toString();
console.log(s);

执行结果:

//crosswalk.polygon对应的结果
{ point:
   [ { x: 423922.8944351942, y: 4437973.431033986, z: 0 },
     { x: 423922.7339226657, y: 4437967.6526591815, z: 0 },
     { x: 423925.9441333221, y: 4437967.732915576, z: 0 },
     { x: 423926.0243883391, y: 4437973.270524149, z: 0 } ] }
{ point:
   [ { x: 423914.73320258665, y: 4437978.532420581, z: 0 },
     { x: 423914.6474643292, y: 4437975.474386045, z: 0 },
     { x: 423920.8778520636, y: 4437975.4172263285, z: 0 },
     { x: 423920.9635903211, y: 4437978.475260865, z: 0 } ] }
{ point:
   [ { x: 423914.47022422304, y: 4437965.047468535, z: 0 },
     { x: 423914.41278616997, y: 4437962.175576869, z: 0 },
     { x: 423920.64478896017, y: 4437962.031982604, z: 0 },
     { x: 423920.7022270133, y: 4437965.018748728, z: 0 } ] }
     
//version对应的结果
北京市_1.5.0.7

如果有什么问题欢迎下发留言

猜你喜欢

转载自blog.csdn.net/len_yue_mo_fu/article/details/84967448