您的位置:首页 > 其它

基于rsync+inotify实现数据实时同步传输

2015-05-20 10:53 561 查看
一、简单介绍&编译
protocol buffer 是 google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。本文通过一个简单的示例介绍 protocol buffer。

在开始之前需要下载 protocol buffer 的编译器和相应类库。下载地址为:http://code.google.com/p/protobuf/downloads/list 。当前版本为 2.3.0,下载一下两个压缩包:protoc-2.3.0-win32.zip 和 protobuf-2.3.0.zip,前者是 protocol buffer 编译器,后者包含了三种语言的开发包。

首先解压 protoc-2.3.0-win32.zip,把 protoc.exe 文件放到 path 路径中,最简单的就是把这个文件复制到 c:\windows 目录中。

解压 protobuf-2.3.0.zip 文件,假设解压后的目录为 proto_home。由于此开发包中只包含了源文件,没有包含打包后的 jar 文件,所以需要自己手动编译。下面一步一步来编译 protocol buffer 的 java 实现,由于 protocol buffer 使用 maven 作为编译工具,所以必须先下载安装 maven,maven 可以从 http://maven.apache.org 上下载。安装 maven 非常简单,只要解压并把 bin 目录添加到 path 中即可。安装好 maven 后,测试一下 maven 是否安装成功,打开命令行窗口,运行命令 mvn -version,当看到相关maven信息输出后,说明 maven 安装成功。

在编译之前还需把 protocol buffer 的编译器复制一份到把 protocol buffer 的编译器复制一份到目录 proto_home\src\ 中,由于在 maven 脚本中调用了这个文件。下面在命令行窗口中把当前工作目录定位到proto_home\java 中,运行命令 mvn package。编译完成后会在 taget 目录中生成一个 jar 文件 protobuf-java-2.3.0.jar。

protocol buffer 的编译器和基于 java 的类库已经准备好了,下面可以使用 protocol buffer 写一个简单的示例。本文中就直接使用 protocol buffer 本身自带的一些示例,这个示例在 proto_home\examples 目录中。这个示例会用到这个目录中的 addressbook.proto、AddPerson.java 和 ListPerson.java 文件。下面一步一步来运行这些示例。

首先把前面编译生成的 protobuf-java-2.3.0.jar 复制到 proto_home\examples 目录中,便于引用。

使用 protocol buffer 编译器编译 addressbook.proto 文件。打开命令行窗口,并定位到 proto_home\examples 目录中,运行命令 protoc --java_out=. addressbook.proto,执行这个命令后会在当前目录下生成一个java类 com.example.tutorial.AddressBookProtos.java。

生成了 java 类之后就是编译并运行这个示例,在命令行中执行命令 javac -d . -classpath .;protobuf-java-2.3.0.jar AddPerson.java ListPeople.java com\example\tutorial\AddressBookProtos.java。

下面运行 AddPerson,在命令中执行命令 java -cp .;protobuf-java-2.3.0.jar AddPerson addr.dat,按照提示输入相应的信息

运行这个程序会在当前目录中创建一个数据文件 addr.dat 保存 protocol buffer 生成的数据。运行程序 ListPeople 则可以读取 addr.dat 文件中的数据。
java -cp .;protobuf-java-2.3.0.jar ListPeople addr.dat

注:
1、如果使用maven编译出错,下面提供编译好的protobuf-java-2.4版本的jar包;
2、使用protoc编译不好使,则将protoco.exe拷贝到examples目录下,使用protoco.exe命令执行;

二、定义Proto文件

proto文件即消息协议原型定义文件,在该文件中我们可以通过使用描述性语言,来良好的定义我们程序中需要用到数据格式。首先我们可以通过Google在线文档上提供的一个电话簿的例子来了解下,不过稍微加了点改动。

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];
}

repeated PhoneNumber phone = 4;

required bytes unsure = 5; //Add byte array here
}

message AddressBook {
repeated Person person = 1;
}
诚如你看到的一样,消息格式定义很简单,对于每个字段而言都有一个修饰符(required/repeated/optional)、字段类型(bool/string/bytes/int32等)和字段标签(Tag)组成。

三个修饰符从词义上可以很清楚的弄明白,

1)对于required的字段而言,初值是必须要提供的,否则字段的便是未初始化的。在Debug模式的buffer库下编译的话,序列化话的时候可能会失败,而且在反序列化的时候对于该字段的解析会总是失败的。所以,对于修饰符为required的字段,请在序列化的时候务必给予初始化。

2)对于optional的字段而言,如果未进行初始化,那么一个默认值将赋予该字段,当然也可以指定默认值,如上述proto定义中的PhoneType字段类型。

3)对于repeated的字段而言,该字段可以重复多个,google提供的这个addressbook例子便有个很好的该修饰符的应用场景,即每个人可能有多个电话号码。在高级语言里面,我们可以通过数组来实现,而在proto定义文件中可以使用repeated来修饰,从而达到相同目的。当然,出现0次也是包含在内的。

其中字段标签标示了字段在二进制流中存放的位置,这个是必须的,而且序列化与反序列化的时候相同的字段的Tag值必须对应,否则反序列化会出现意想不到的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: