0

0

ProtocolBuffers的基础说明和使用

php中文网

php中文网

发布时间:2016-06-07 16:12:27

|

1406人浏览过

|

来源于php中文网

原创

我们开始需要使用protobuf的原因是,在处理OJ的contest模块的时候,碰到一个问题就是生成contestRank的时候,需要存储很多信息。如果我们采用model存储的话,那么一方面后续如果继续加入其他信息的话修改会灰常麻烦,另一方面就是实现比较复杂,因为对于rank

我们开始需要使用protobuf的原因是,在处理oj的contest模块的时候,碰到一个问题就是生成contestrank的时候,需要存储很多信息。如果我们采用model存储的话,那么一方面后续如果继续加入其他信息的话修改会灰常麻烦,另一方面就是实现比较复杂,因为对于rank来说,每一条rank的主键首先是userid,其次存储的基本信息有ac数,题目ac情况,罚时等等,其中题目ac情况又包括以题目id为主键,属性(是否ac,ac时间,罚时,这道题目的提交统计),而每一道题目的提交统计又是一个submit实体,这样的话,就会有多级嵌套存在。如果后续添加的话会更多。还有一个原因就是存储也不方便,逻辑构思不是很明确,需要注意保存各种信息,实现复杂。

protobuf的主要机理是把存储的信息序列化为一个字符串存储,需要信息的时候又可以逆序列化把原始信息还原出来,而且可以实现多级嵌套的属性。所以就尝试使用这个来解决rank的存储(/ □ \)

1:protobuf是什么?

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

简单地说,就是把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。

2:下载安装:

地址:http://code.google.com/p/protobuf/downloads/list

安装:

 tar -xzf protobuf-2.1.0.tar.gz 
 cd protobuf-2.1.0 
 ./configure  
 make 
 make check 
 make install

3:使用建立

网上有各种例子,比如简单的book的书写等等都可以用来练习操作

首先,首先我们需要编写一个 proto 文件,定义我们程序中需要处理的结构化数据,在 protobuf 的术语中,结构

化数据被称为 Message。例如:

package contest_submit;
 message ContestSubmit {
   required int32 id = 1;
   required int64 timestamp = 2;
 }

上述例子中id是int32的,timestamp是int64的。required代表这个是必须的,有点像数据库里的not null,还有一

种就是optional,即可选的。

编译.proto文件,命令如下:

protoc -I=./ --python_out=./ ./*.proto

代表的意思是输入的.proto文件在当前目录,输出生成的编译文件到当前目录,源文件是所有以.proto结尾的文件

佳可商务购物程序 2004
佳可商务购物程序 2004

在原版的基础上做了一下修正评论没有提交正文的问题特价商品的调用连接问题去掉了一个后门补了SQL注入补了一个过滤漏洞浮动价不能删除的问题不能够搜索问题收藏时放入购物车时出错点放入购物车弹出2个窗口修正主题添加问题商家注册页导航连接问题销售排行不能显示更多问题热点商品不能显示更多问题增加了服务器探测 增加了空间使用查看 增加了在线文件编辑增加了后台管理里两处全选功能更新说明:后台的部分功能已经改过前台

下载

。网上完整的格式是:

假设您的 proto 文件存放在 $SRC_DIR 下面,您也想把生成的文件放在同一个目录下,则可以使用如下命令:
 protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/文件明.proto

编译完成之后会生成 contest_submit_pb2.py文件(对于上面的例子来说)

当然,protobuf也是可以嵌套的。即可以在一个类中声明另一个类的对象,例如,rank的实现:

package contest_rank;
 message Submit {
   optional string status = 1;
   optional string date_time = 2;
   optional string runID = 3;
 }
 
 message Problem {
   optional int32 problemID = 1;
   repeated Submit submit = 2;
   optional int32 acindex = 3;
   optional int32 totalindex = 4;
   optional int32 time = 5;
   optional int32 FB = 6;
 }
 
 message Rank {
   optional string userID = 1;
   optional string contestID = 2;
   repeated Problem problem = 3;
   optional int32 penalty = 4;
   optional int32 ac = 5;
   optional int32 total = 6;
 }
 
 message ContestRankList {
   optional string contestID = 1;
   repeated Rank rank = 2;
 }
这样的话,就可以实现我们前面的需求即多级信息嵌套了。

使用:

首先,要记得载入头文件from 文件夹.proto import rank_pb2

对于实现rank的存储的时候,首先声明一个rank类,以便后续对数据的处理

class Rank():
   class Problem():
     class Submit():
       def __init__(self, runID = "", status="", date_time=""):
         self.status = status
         self.date_time = date_time
         self.runID = runID
 
     def __init__(self, problemID):
       self.problemID = problemID
       self.submit_list = []
       self.acindex = 0
       self.totalindex = 0
       self.time = 0
       self.FB = 0
 
     def add_submit(self, submit):
       self.submit_list.append(submit)
 
   def __init__(self, userID, contestID):
     self.userID = userID
     self.contestID = contestID
     self.problem_list = {}
     self.ac = 0
     self.penalty = 0
     self.total = 0
 
当我们得到rank_list的时候(rank_list是一个存放rank的字典),首先声明一个proto的载体:

contest_rank_list = rank_pb2.ContestRankList()
然后填充信息,比如先把比赛的ID加入,即contest_rank_list.contestID = contestID。然后按照protobuf的结构,依

次把需要的信息填入。对于嵌套的实体来说,每次声明的时候可以使用add()方法,比如在一个比赛中,会有多个用户

的rank信息存在,所以按照用户ID来添加信息:

rank_proto = contest_rank_list.rank.add()
rank.load_data_to_proto(rank_proto)
其中的load_data_to_proto是rank类的一个方法,内容就是把信息加入到protobuf里面而已:

def load_data_to_proto(self, rank):
     rank.userID = self.userID
     rank.contestID = self.contestID
     rank.ac = self.ac
     rank.penalty = self.penalty
     rank.total = self.total
 
     for problemID in self.problem_list:
       problem = self.problem_list[problemID]
       p = rank.problem.add()
       p.problemID = problem.problemID
       p.acindex = problem.acindex
       p.totalindex = problem.totalindex
       p.time = problem.time
       p.FB = problem.FB
       for submit in problem.submit_list:
         s = p.submit.add()
         s.status = submit.status
         s.date_time = submit.date_time
         s.runID = submit.runID
     return rank
 
这样我们就把数据存入了我们声明的protobuf里面了,然后就是存储的时候序列化,比如我们存储到SSDB里面即:

ssdb_api.SetContestRankListProto(contestID, contest_rank_list.SerializeToString())

至此,信息已经存入数据库,那么接下来就是如何读出了:

对于得到我们存储的rank信息来说,即:

 contest_rank_list = ssdb_api.GetContestRankListProto(contest_id)
 rank_list = rank_pb2.ContestRankList()
 rank_list.ParseFromString(contest_rank_list)
即,再次声明一个protobuf的对象,然后逆序列化,就得到了我们需要的信息,简单吧(/ □ \)。

后面需要的数据,就用父名.子名访问即可。




相关专题

更多
虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

29

2025.12.25

错误代码dns_probe_possible
错误代码dns_probe_possible

本专题整合了电脑无法打开网页显示错误代码dns_probe_possible解决方法,阅读专题下面的文章了解更多处理方案。

20

2025.12.25

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

37

2025.12.25

word转换成ppt教程大全
word转换成ppt教程大全

本专题整合了word转换成ppt教程,阅读专题下面的文章了解更多详细操作。

6

2025.12.25

msvcp140.dll丢失相关教程
msvcp140.dll丢失相关教程

本专题整合了msvcp140.dll丢失相关解决方法,阅读专题下面的文章了解更多详细操作。

2

2025.12.25

笔记本电脑卡反应很慢处理方法汇总
笔记本电脑卡反应很慢处理方法汇总

本专题整合了笔记本电脑卡反应慢解决方法,阅读专题下面的文章了解更多详细内容。

6

2025.12.25

微信调黑色模式教程
微信调黑色模式教程

本专题整合了微信调黑色模式教程,阅读下面的文章了解更多详细内容。

5

2025.12.25

ps入门教程
ps入门教程

本专题整合了ps相关教程,阅读下面的文章了解更多详细内容。

4

2025.12.25

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

218

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 3.8万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 1.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号