Protocol Buffers的基础说明和使用
我们開始须要使用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结尾的文件
。
网上完整的格式是:
如果您的 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的对象,然后逆序列化。就得到了我们须要的信息。简单吧(/ □ \)。
后面须要的数据。就用父名.子名訪问就可以。
Protocol Buffers的基础说明和使用的更多相关文章
- Hadoop基础-Protocol Buffers串行化与反串行化
Hadoop基础-Protocol Buffers串行化与反串行化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们之前学习过很多种序列化文件格式,比如python中的pickl ...
- 使用 Protocol Buffers 代替 JSON 的五个原因
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 在centos 6.9下Protocol Buffers数据传输及存储协议的使用(python)
我们知道Protocol Buffers是Google定义的一种跨语言.跨平台.可扩展的数据传输及存储的协议,因为将字段协议分别放在传输两端,传输数据中只包含数据本身,不需要包含字段说明,所以传输数据 ...
- Google Protocol Buffers 快速入门(带生成C#源码的方法)
Google Protocol Buffers是google出品的一个协议生成工具,特点就是跨平台,效率高,速度快,对我们自己的程序定义和使用私有协议很有帮助. Protocol Buffers入门: ...
- 让Web API支持Protocol Buffers
简介 现在我们Web API项目基本上都是使用的Json作为通信的格式,随着移动互联网的兴起,Web API不仅其他系统可以使用,手机端也可以使用,但是手机端也有相对特殊的地方,网络通信除了wifi, ...
- Xml,Json,Hessian,Protocol Buffers序列化对比
简介 这篇博客主要对Xml,Json,Hessian,Protocol Buffers的序列化和反序列化性能进行对比,Xml和Json的基本概念就不说了. Hessian:Hessian是一个轻量级的 ...
- Protocol buffers 介绍
Protocol buffers和mxl一样在序列化数据结构时很灵活.高效和智能,但是它的优势在于定义文件更小,读取速度更快,使用更加简单.目前protocol buffers支持C++.java和p ...
- C#/net 使用Protocol Buffers入门
Protocol buffers 是一个由谷歌开发的开源的编码机制用于将结构化的数据序列化或者反序列化,被设计成语言以及平台中立,protobuff比xml更简单比json还要紧凑一些,网上有一些关于 ...
- java&Protocol Buffers
ps: Protocol Buffers简称PB PB 安装配置 下载 PB: 在 PB 官网,下载最新版(或者其他版本)PB,这里为了与 Java 项目中的 PB Maven 依赖版本一致,使用 P ...
随机推荐
- echars自定义提示框位置
tooltip: { trigger: 'item', formatter: "{a} <br/>{b}: {c} ({d}%)", position:function ...
- FFT&NTT学习笔记
具体原理就不讲了qwq,毕竟证明我也不太懂 FFT(快速傅立叶变换)&NTT(快速数论变换) FFT //求多项式乘积 //要求多项式A和多项式B的积多项式C //具体操作就是 //DFT(A ...
- red hat linux之Samba、DHCP、DNS、FTP、Web的安装与配置
本教程是在red hat linux 6.0环境下简单测试!教程没有图片演示,需要具有一定Linux基础知识,很多地方的配置需要根据自己的情况修改,照打不一定可以配置成功.(其他不足后续修改添加) y ...
- python学习笔记:第五天
day05: 1.字符串格式化输出: 1.占位符:%s (字符串) %d(整型) %f (浮点型) 打印格式:print("字符串为%s" %s) 2.字符串:判断是否是 ...
- docker下修改mysql配置文件
原文:docker下修改mysql配置文件 版权声明:本文为博主原创文章,转载注明地址:http://blog.csdn.net/wang704987562 https://blog.csdn.net ...
- 什么是面向对象以及其意义,prototpye原型
什么是面向对象: 使用对象时,只关注对象提供的功能,不关注其内部的细节 例如:jquery 什么是对象: 对象是一个整体对外提供一些操作,比如 收音机 面向对象编程OOP的特点: 1.抽象:把主要的特 ...
- 精品JS代码收藏大全
1. oncontextmenu="window.event.returnvalue=false" 将彻底屏蔽鼠标右键 <table border oncontextmenu ...
- JavaScript检查手机格式是否错误
编写自己定义的JavaScript函数checkPhone(),在函数中应用正則表達式推断手机号码的格式是否正确,不对的给出提示 <script type="text/javascri ...
- 数学之路-python计算实战(18)-机器视觉-滤波去噪(双边滤波与高斯滤波 )
高斯滤波就是对整幅图像进行加权平均的过程.每个像素点的值,都由其本身和邻域内的其它像素值经过加权平均后得到.高斯滤波的详细操作是:用一个模板(或称卷积.掩模)扫描图像中的每个像素.用模板确定的邻域内像 ...
- 生成apk文件遇到的编译问题error: format not a string literal and no format arguments
编译错误时使用的android-ndk为r9的版本号.报下面错误: "Compile++ thumb : cocosdenshion_static <= SimpleAudioEngi ...