2020-04-09vue中使用protobuf
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020-04-09vue中使用protobuf相关的知识,希望对你有一定的参考价值。
参考技术A 1. 安装protobuf转换 npm i protobufjs2. 在src目录结构下建一个文件夹proto(叫什么名字都行)
3. 将.proto文件拷贝到proto文件夹下
4. 在package.json文件中添加proto生成命令
pbjs -t static-module -w commonjs -o src/proto/proto.js src/proto/*.proto
5. 然后在CMD中进入本项目文件夹执行npm run proto即可在proto文件夹下生成proto.js文件
6. 如果proto.js在使用时出现报错问题是因为导出语法问题,改成<kbd>export default</kbd>即可
7. 如有疑问可以留言
C++编程中使用框架protobuf
protobuf作为protocol buffer协议使用最广泛的框架之一,在很多编程语言中都有对应实现,本篇文章介绍以下C++语言中如何使用protobuf。
目录
4.3CodedOutputStream与CodedInputStream使用
编辑 4.5FileOutputStream和FileInputStream操作二进制文件
1.编译安装protobuf
参考博客:
protocol buffer协议的两种常用框架protobuf和nanopb_nanopb repeated_hsy12342611的博客-CSDN博客
2.Protobuf2和Protobuf3
Protobuf有两个版本,Protobuf2和Protobuf3,目前使用最多是Protobuf3,关于Protobuf2和Protobuf3,有如下点需要说明
(1)在Protobuf2中,消息的字段可以加required和optional修饰符,也支持default修饰符指定默认值。默认一个optional字段如果没有设置,或者显式设置成了默认值,在序列化成二进制格式时,这个字段会被去掉,反序列化后,无法区分是当初没有设置还是设置成了默认值但序列化时被去掉了,虽然Protobuf2对于原始数据类型字段都有hasXxx()方法,在反序列化后,对于这个“缺失”字段,hasXxx()总是false,因此失去了其判定意义。
(2)在 Protobuf3中,去掉了required和optional修饰符,所有字段都是optional的,而且对于原始数据类型字段(包括repeated),不提供hasXxx()方法。
(3)缺失值和默认
缺失值或者显示设置默认值,效果是一样,序列化时字段会被去掉。
对于整数类型,默认值为0。
对于字符串,默认值为空字符串。
对于字节,默认值为空字节。
对于布尔值,默认值为false。
对于数字类型,默认值为零。
对于枚举,默认值为第一个定义的枚举值,必须为0。
3.定义proto接口文件
以表达人信息为例,对比Protobuf2和Protobuf3定义person.proto
3.1Protobuf2定义
syntax = "proto2";
package cunion.test;
// proto2
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];
optional repeated PhoneNumber phone = 4;
message Addr
optional string province = 1;
optional string city = 2;
optional string county = 3;
optional Addr addr = 5;
3.2Protobuf2定义
syntax = "proto3";
package cunion.test;
// proto3
message Person
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType
MOBILE = 0;
HOME = 1;
WORK = 2;
message PhoneNumber
string number = 1;
PhoneType type = 2;
repeated PhoneNumber phone = 4;
message Addr
string province = 1;
string city = 2;
string county = 3;
Addr addr = 5;
4.C++语言中使用protobuf
本人安装是protobuf V3.6.1版本,所以就以protobuf3为例介绍C++中使用protobuf框架。
4.1生成C++接口文件
/home/tiger/protobuf-3.6.1/protobuf/bin/protoc -I=/home/tiger/cpp/protocalbuffer --cpp_out=/home/tiger/cpp/protocalbuffer person.proto
4.2PB对象与字节流互转,PB对象与文件流
#include <algorithm>
#include <iostream>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "person.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h" // ArrayOutputStream
#include "google/protobuf/io/zero_copy_stream_impl.h" // FileOutputStream OstreamOutputStream
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/delimited_message_util.h"
// ArrayOutputStream, FileOutputStream, OstreamOutputStream
// ArrayInputStream, FileInputStream, OstreamInputStream均继承ZeroCopyOutputStream
using namespace ::cunion::test;
using namespace std;
// PB对象与字节流互转,PB对象与文件流
int use_1()
Person person1;
person1.set_name("hello tree");
//person1.has_phone(); //error
std::cout << person1.has_addr() << std::endl;
std::cout << "person1 " << person1.DebugString() << std::endl;
std::string strPerson1;
//PB对象转字节流
person1.SerializeToString(&strPerson1); // person1.SerializeToArray(buffer, n);
Person person2;
//字节流转PB对象
person2.ParseFromString(strPerson1);
std::cout << person2.has_addr() << std::endl;
std::cout << "person2 " << person2.DebugString() << std::endl;
const char* fileName = "person.bin";
// 写文件
std::fstream output(fileName, ios::out | ios::binary);
if (!output)
cout<< "output" << fileName << " error"<<endl;
//PB对象转文件流
person1.SerializeToOstream(&output);
output.close();
// 读文件
fstream input(fileName, ios::in | ios::binary);
if (!input)
cout<<"input "<< fileName << " error"<<endl;
return -1;
Person person3;
//文件流转PB对象
if (!person3.ParseFromIstream(&input))
cerr << "person3.ParseFromIstream !"<< endl;
std::cout << "person3 " << person2.DebugString() << std::endl;
int main()
GOOGLE_PROTOBUF_VERIFY_VERSION;
use_1();
google::protobuf::ShutdownProtobufLibrary();
return 0;
编译:
//错误编译方法1
g++ person.pb.cc main.cpp -I /home/tiger/protobuf-3.6.1/protobuf/include -lpthread -L /home/tiger/protobuf-3.6.1/protobuf/lib -lprotobuf
//错误编译方法2
g++ -I /home/tiger/protobuf-3.6.1/protobuf/include -L /home/tiger/protobuf-3.6.1/protobuf/lib -lpthread -lprotobuf person.pb.cc main.cpp
// 正确编译方法
g++ -I /home/tiger/protobuf-3.6.1/protobuf/include person.pb.cc main.cpp -L /home/tiger/protobuf-3.6.1/protobuf/lib -lprotobuf -lpthread
运行:
export LD_LIBRARY_PATH=/home/tiger/protobuf-3.6.1/protobuf/lib
./a.out
运行结果如下:
4.3CodedOutputStream与CodedInputStream使用
#include <algorithm>
#include <iostream>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "person.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h" // ArrayOutputStream
#include "google/protobuf/io/zero_copy_stream_impl.h" // FileOutputStream OstreamOutputStream
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/delimited_message_util.h"
// ArrayOutputStream, FileOutputStream, OstreamOutputStream
// ArrayInputStream, FileInputStream, OstreamInputStream均继承ZeroCopyOutputStream
using namespace ::cunion::test;
using namespace std;
// CodedOutputStream与CodedInputStream使用
int use_2()
Person person;
person.set_name("hello liudehua");
int len = person.ByteSize();
char *buffer = new char[len];
memset(buffer, 0, len);
std::shared_ptr<char> pBuf;
pBuf.reset(buffer);
//写入pBuf
google::protobuf::io::ArrayOutputStream arrayOut(pBuf.get(), len);
google::protobuf::io::CodedOutputStream codedOut(&arrayOut);
codedOut.WriteVarint32(len);
person.SerializeToCodedStream(&codedOut);
std::cout << "person " << person.DebugString() << std::endl;
//读取pBuf
Person person1;
google::protobuf::io::ArrayInputStream array_in(pBuf.get(), len);
google::protobuf::io::CodedInputStream coded_in(&array_in);
google::protobuf::uint32 size;
coded_in.ReadVarint32(&size);
google::protobuf::io::CodedInputStream::Limit msg_limit = coded_in.PushLimit(size);
person1.ParseFromCodedStream(&coded_in);
coded_in.PopLimit(msg_limit);
std::cout << "person1 " << person1.DebugString() << std::endl;
int main()
GOOGLE_PROTOBUF_VERIFY_VERSION;
use_2();
google::protobuf::ShutdownProtobufLibrary();
return 0;
编译运行:
g++ -I /home/tiger/protobuf-3.6.1/protobuf/include person.pb.cc main.cpp -L /home/tiger/protobuf-3.6.1/protobuf/lib -lprotobuf -lpthread
./a.out
运行结果如下:
通过运行结果看:
google::protobuf::io::ArrayOutputStream和google::protobuf::io::CodedOutputStream实现PB对象的序列化,google::protobuf::io::ArrayInputStream和google::protobuf::io::CodedInputStream实现反序列化。
4.4prototxt文本文件写和读
#include <algorithm>
#include <iostream>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "person.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h" // ArrayOutputStream
#include "google/protobuf/io/zero_copy_stream_impl.h" // FileOutputStream OstreamOutputStream
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/delimited_message_util.h"
// ArrayOutputStream, FileOutputStream, OstreamOutputStream
// ArrayInputStream, FileInputStream, OstreamInputStream均继承ZeroCopyOutputStream
using namespace ::cunion::test;
using namespace std;
// FileOutputStream FileInputStream
// prototxt文本文件
int use_3()
const char* fileName = "person1.prototxt";
// 写入
int fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, 0777);
google::protobuf::io::FileOutputStream * output = new google::protobuf::io::FileOutputStream(fd);
Person person;
person.set_name("hello guofucheng");
person.set_id(110);
google::protobuf::TextFormat::Print(person, output);
delete output;
close(fd);
std::cout << "person " << person.DebugString() << std::endl;
// 读取
fd = open(fileName, O_RDONLY);
Person person1;
google::protobuf::io::FileInputStream * input = new google::protobuf::io::FileInputStream(fd);
bool success = google::protobuf::TextFormat::Parse(input, &person1);
delete input;
close(fd);
std::cout << "person1 " << person1.DebugString() << std::endl;
int main()
GOOGLE_PROTOBUF_VERIFY_VERSION;
use_3();
google::protobuf::ShutdownProtobufLibrary();
return 0;
运行结果如下:
4.5FileOutputStream和FileInputStream操作二进制文件
#include <algorithm>
#include <iostream>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "person.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h" // ArrayOutputStream
#include "google/protobuf/io/zero_copy_stream_impl.h" // FileOutputStream OstreamOutputStream
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/delimited_message_util.h"
// ArrayOutputStream, FileOutputStream, OstreamOutputStream
// ArrayInputStream, FileInputStream, OstreamInputStream均继承ZeroCopyOutputStream
using namespace ::cunion::test;
using namespace std;
// FileOutputStream和FileInputStream操作二进制文件
int use_4()
const char* fileName = "person3.bin";
// 写入
int fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, 0777);
google::protobuf::io::ZeroCopyOutputStream* raw_output = new google::protobuf::io::FileOutputStream(fd);
google::protobuf::io::CodedOutputStream* coded_output = new google::protobuf::io::CodedOutputStream(raw_output);
Person person;
person.set_name("hello zhangxueyou");
person.set_id(119);
coded_output->WriteVarint32(person.ByteSize());
person.SerializeToCodedStream(coded_output);
Person person1;
person1.set_name("hello liming");
person1.set_id(120);
coded_output->WriteVarint32(person1.ByteSize());
person1.SerializeToCodedStream(coded_output);
person1.set_name("hello xijinping");
person1.set_id(121);
coded_output->WriteVarint32(person1.ByteSize());
person1.SerializeToCodedStream(coded_output);
person1.set_name("hello liqiang");
person1.set_id(122);
coded_output->WriteVarint32(person1.ByteSize());
person1.SerializeToCodedStream(coded_output);
delete coded_output;
delete raw_output;
close(fd);
std::cout << "person " << person.DebugString() << std::endl;
std::cout << "person1 " << person1.DebugString() << std::endl;
// 读取
fd = open(fileName, O_RDONLY);
google::protobuf::io::FileInputStream fin(fd);
Person person2;
google::protobuf::io::FileInputStream input(fd);
google::protobuf::io::CodedInputStream codedIn(&input);
google::protobuf::uint32 size;
while (true)
if (!codedIn.ReadVarint32(&size))
return -1;
std::cout << "person2 " << size << std::endl;
google::protobuf::io::CodedInputStream::Limit msg_limit = codedIn.PushLimit(size);
person2.ParseFromCodedStream(&codedIn);
codedIn.PopLimit(msg_limit);
std::cout << "person2 " << person2.DebugString() << std::endl;
int main()
GOOGLE_PROTOBUF_VERIFY_VERSION;
use_4();
google::protobuf::ShutdownProtobufLibrary();
return 0;
运行结果如下:
4.6PB对象与std::stringstream
#include <algorithm>
#include <iostream>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "person.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h" // ArrayOutputStream
#include "google/protobuf/io/zero_copy_stream_impl.h" // FileOutputStream OstreamOutputStream
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/delimited_message_util.h"
// ArrayOutputStream, FileOutputStream, OstreamOutputStream
// ArrayInputStream, FileInputStream, OstreamInputStream均继承ZeroCopyOutputStream
using namespace ::cunion::test;
using namespace std;
// std::stringstream
int use_5()
std::stringstream stream;
Person person;
person.set_name("name one");
person.set_id(1);
google::protobuf::util::SerializeDelimitedToOstream(person, &stream);
person.set_name("name two");
person.set_id(2);
google::protobuf::util::SerializeDelimitedToOstream(person, &stream);
person.set_name("name three");
person.set_id(3);
google::protobuf::util::SerializeDelimitedToOstream(person, &stream);
person.set_name("name four");
person.set_id(4);
google::protobuf::util::SerializeDelimitedToOstream(person, &stream);
bool keep = true;
bool clean_eof = true;
Person person1;
google::protobuf::io::IstreamInputStream zstream(&stream);
while (keep)
clean_eof = true;
keep = google::protobuf::util::ParseDelimitedFromZeroCopyStream(&person1, &zstream, &clean_eof);
std::cout << person1.name() << " " << person1.id() << std::endl;
return 0;
int main()
GOOGLE_PROTOBUF_VERIFY_VERSION;
use_5();
google::protobuf::ShutdownProtobufLibrary();
return 0;
运行结果如下:
从上面的举例可以看出protobuf框架对C++提供了丰富的操作API,利用这些API可以很容易处理java,python等语言处理过后的PB文件流。
以上是关于2020-04-09vue中使用protobuf的主要内容,如果未能解决你的问题,请参考以下文章