日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ java通信 protocol buffer,google protocol buffer (C++,Java序列化应用实例)

發布時間:2023/12/10 c/c++ 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ java通信 protocol buffer,google protocol buffer (C++,Java序列化应用实例) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

google protocol buffer (C++,Java序列化使用實例)

轉載,請注明出處:?http://blog.csdn.net/eclipser1987/article/details/8525383 ?(eclipser@163.com)

1.下載安裝:

google protocol buffer?的官網地址是:http://code.google.com/p/protobuf/

建議下載穩定版本:protobuf-2.4.1 ?linux下載protobuf-2.4.1.tar.bz2 ? windows下載protobuf-2.4.1.zip

這里以linux下安裝為實例:

tar -xvf?protobuf-2.4.1.tar.bz2

cd?protobuf-2.4.1

./configure --prefix=/usr/local/protobuf-2.4.1

make

make install

2.使用protobuf

查看編譯生成的目錄

cd /usr/local/protobuf-2.4.1

ls

bin ?include ?lib

其中,bin中的protoc是.proto文件的處理器,可用這個工具生成cpp,java,python文件.

由于系統常用這個工具,可以將其ln或者直接拷貝到系統環境bin下

ln -s?/usr/local/protobuf-2.4.1/bin/protoc /usr/bin/protoc

同樣,可以將頭文件ln或者直接拷貝到系統環境

ln -s?/usr/local/protobuf-2.4.1/include/google /usr/include/google

將lib文件ln或者直接拷貝到系統環境

略,方法同上.

這個時候,protobuf的開發環境已經搭建了.

3.如何使用protobuf

數據結構體:

message message_name{message_body;}

message_body格式:

例如required int32 query = 1[defaut=10];

形式為:rule type name = value[other_rule];

規則:

required表示必須具有該值域;

optional表示可選的值域;

repeated表示可重復的值域(即>=0);

其中requered/optional是常用rule,而repeated則不常用同時因為是歷史遺留現使用repeated int32 samples=4[packed=true];形式;

value值:

value值最小為1,是底層編碼時使用其中1-15占一位,>15則會占多位;

不同的message中的value值互不干擾,常以1開始計數。

數據類型之基本類型:

.proto Type C++ Type Java Type

double double double

float float float

int32 int32 int

int64 int64 long

uint32 uint32 int

uint64 uint64 long

sint32 int32 int

sint64 int64 long

fixed32 uint32 int

fixed64 uint64 long

sfixed32 int32 int

sfixed64 int64 long

bool bool boolean

string string String

bytes string ByteString

數據類型之復雜類型:

復雜類型主要包括:枚舉,其他message,groups等。

枚舉定義例如:enum Corpus{WEB=0;LOCAL=1}

枚舉定義在message中。

可以使用其他message作為類型來定義成員。

groups我的理解有些像C++中的union結構。

嵌套定義:

可以嵌套定義message結構,而嵌套定義的message被其他message作為成員類型時需要形式為outmessage.inmessage形式。

包結構:

定義形式:package foo.bar;

對應C++中則生成兩個命名空間foo和bar,且bar定義在foo中;

可以通過import "myproject/other_protos.proto";來引入.proto文件;

引用其他package中message時需要完整的package路徑;

Services:

主要用于RPC系統中,在.proto中定義接口;

定義形式如例子:

service SearchService {

rpc Search(SearchRequest) return (SearchResponse);

}

.proto文件編譯:

格式:

protoc -–proto_path=(.proto文件路徑) -–cpp_out=(.cc .java生成文件路徑) (.proto文件路徑)/?.proto

-–proto_path 簡化為: --I

其中可根據需要更改:cpp_out選項為java_out/python_out。

例子:

protoc -I=./ --cpp_out=./ model.proto

我們拿個例子:

建立model.proto

package cn.vicky.model.seri;

message User {

required int32 id = 1; // 主鍵,唯一

required string username = 2; // 帳號

required string password = 3; // 密碼

optional string email = 4; // 郵箱(可選)

repeated Person person = 5; // 賬戶擁有的角色(可以重復)

}

message Person {

required int32 id = 1; // 主鍵,唯一

required string name = 2; // 角色名字

repeated PhoneNumber phone = 3; // 電話號碼(可以重復)

}

// 枚舉類型

enum PhoneType {

MOBILE = 0;

HOME = 1;

WORK = 2;

}

message PhoneNumber {

required string number = 1;

optional PhoneType type = 2 [default = HOME];

}

protoc -I=./ --cpp_out=./ model.proto

將生成對應的model.pb.h ?model.pb.cc

使用:

編寫main.cpp

/*

* File: main.cpp

* Author: Vicky.H

* Email: eclipser@163.com

*/

#include

#include

#include "model.pb.h"

/*

*

*/

int main(void) {

// 創建User對象

cn::vicky::model::seri::User u;

u.set_id(1);

u.set_username("Jack");

u.set_password("123456");

u.set_email("289997171@qq.com");

// 創建User中的一個角色

cn::vicky::model::seri::Person* _person1 = u.add_person();

_person1->set_id(1);

_person1->set_name("P1");

// 創建角色中的一個電話號碼:1

cn::vicky::model::seri::PhoneNumber* _phone1 = _person1->add_phone();

_phone1->set_number("+8613618074943");

_phone1->set_type(cn::vicky::model::seri::MOBILE);

// 創建角色中的一個電話號碼:2

cn::vicky::model::seri::PhoneNumber* _phone2 = _person1->add_phone();

_phone2->set_number("02882334717");

_phone2->set_type(cn::vicky::model::seri::WORK);

// 創建User中的一個角色

cn::vicky::model::seri::Person* _person2 = u.add_person();

_person2->set_id(2);

_person2->set_name("P2");

// 創建角色中的一個電話號碼:1

cn::vicky::model::seri::PhoneNumber* _phone3 = _person2->add_phone();

_phone3->set_number("+8613996398667");

_phone3->set_type(cn::vicky::model::seri::MOBILE);

// 創建角色中的一個電話號碼:2

cn::vicky::model::seri::PhoneNumber* _phone4 = _person2->add_phone();

_phone4->set_number("02882334717");

_phone4->set_type(cn::vicky::model::seri::WORK);

// 持久化:

// std::fstream out("User.pb", std::ios::out | std::ios::binary | std::ios::trunc);

// u.SerializeToOstream(&out);

// out.close();

// 對象化:

cn::vicky::model::seri::User u2;

std::fstream in("User.pb", std::ios::in | std::ios::binary);

if (!u2.ParseFromIstream(&in)) {

std::cerr << "Failed to parse User.pb." << std::endl;

exit(1);

}

std::cout << u2.id() << std::endl;

std::cout << u2.username() << std::endl;

std::cout << u2.password() << std::endl;

std::cout << u2.email() << std::endl;

std::cout << "---------------------------" << std::endl;

for(int i = 0;i < u2.person_size();i++) {

cn::vicky::model::seri::Person* p = u2.mutable_person(i);

std::cout << p->id() << std::endl;

std::cout << p->name() << std::endl;

for (int j = 0;j < p->phone_size();j++) {

cn::vicky::model::seri::PhoneNumber* phone = p->mutable_phone(j);

std::cout << phone->number() << std::endl;

}

std::cout << "---------------------------" << std::endl;

}

return 0;

}

需要 -lpthread -lprotobuf ? ? ? ? ?(protobuf已經被加載到了/usr/lib)

執行后,會生成:User.pb,存儲的二進制文件.可以直接打開看看.

以上,我們使用了protobuf完成c++下的對象序列化以及反序列化.這里我們要描述一下protobuf的優勢了.

那就是protobuf性能高效,他的序列化速度比java自身的序列化還快數倍,而且支持3種語言對象的轉換.以往,在C++中序列化的對象,比如用boost serialization持久化的對象,無法用java展開,即便使用jni技術,這也是非常麻煩的事.現在我們有protobuf了.

運行:?protoc -I=./ --java_out=./ model.proto 將生成對應的Java類

我們可以用Maven建立一個Java工程.需要protobuf的java依賴庫:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

cn.vicky

google_protobuf_01_java

1.0-SNAPSHOT

jar

google_protobuf_01_java

http://maven.apache.org

UTF-8

com.google.protobuf

protobuf-java

2.4.1

編寫Test.java

package cn.vicky.model.seri;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

/**

*

* @author Vicky.H

*/

public class Test {

public static void main(String args[]) throws FileNotFoundException, IOException {

File file = new File("User.pb");

InputStream is = new FileInputStream(file);

Model.User user = Model.User.parseFrom(is);

System.out.println(user.getId());

System.out.println(user.getUsername());

System.out.println(user.getPassword());

System.out.println(user.getEmail());

System.out.println("-------------------");

for (Model.Person person : user.getPersonList()) {

System.out.println(person.getId());

System.out.println(person.getName());

for (Model.PhoneNumber phone : person.getPhoneList()) {

System.out.println(phone.getNumber());

}

System.out.println("-------------------");

}

is.close();

}

}

運行:

1

Jack

123456

289997171@qq.com

---------------------------

1

P1

+8613618074943

02882334717

---------------------------

2

P2

+8613996398667

02882334717

---------------------------

運行 SUCCESSFUL (總時間: ?594ms)

OK.以上我們完成了probuf在C++,Java的使用.非常強力是不是!!

設計思想:

在POJO中,protobuf生成的類,處于PO狀態,而且這個生成的類,我們最好不要做任何修改或太大的修改,那么,這個時候,我們可以通過C++友元類的方式,為PO添加一個JO類.將數據結構算法分離,也就是說,PO是數據,JO放算法!!!

與數據庫的結合:

mysql oracle 可以很輕松的存儲,讀取二進制.還有一點,那就是通過這種方式,我們可以非常簡單的將C++的對象,持久化的redis之類內存數據庫了.

附:

model.proto也可以這樣定義,不過,本人認為,上面的更好,這里僅供參考,采用什么樣的方式,生成的類的結構也不太一樣.

package cn.vicky.model.seri;

message User {

required int32 id = 1; // 主鍵,唯一

required string username = 2; // 帳號

required string password = 3; // 密碼

optional string email = 4; // 郵箱(可選)

message Person {

required int32 id = 1; // 主鍵,唯一

required string name = 2; // 角色名字

// 枚舉類型

enum PhoneType {

MOBILE = 0;

HOME = 1;

WORK = 2;

}

message PhoneNumber {

required string number = 1;

optional PhoneType type = 2 [default = HOME];

}

repeated PhoneNumber phone = 3; // 電話號碼(可以重復)

}

repeated Person person = 5; // 賬戶擁有的角色(可以重復)

}

總結

以上是生活随笔為你收集整理的c++ java通信 protocol buffer,google protocol buffer (C++,Java序列化应用实例)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。