欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

protobuf的編碼和存儲(chǔ)方式

科技綠洲 ? 來(lái)源:Linux開發(fā)架構(gòu)之路 ? 作者:Linux開發(fā)架構(gòu)之路 ? 2023-11-09 09:27 ? 次閱讀

一、protobuf簡(jiǎn)介:

1.1 protobuf的定義:

protobuf是用來(lái)干嘛的?

protobuf是一種用于 對(duì)結(jié)構(gòu)數(shù)據(jù)進(jìn)行序列化的工具,從而實(shí)現(xiàn) 數(shù)據(jù)存儲(chǔ)和交換。

(主要用于網(wǎng)絡(luò)通信中 收發(fā)兩端進(jìn)行消息交互。所謂的“結(jié)構(gòu)數(shù)據(jù)”是指類似于struct結(jié)構(gòu)體的數(shù)據(jù),可用于表示一個(gè)網(wǎng)絡(luò)消息。當(dāng)結(jié)構(gòu)體中存在函數(shù)指針類型時(shí),直接對(duì)其存儲(chǔ)或傳輸相當(dāng)于是“淺拷貝”,而對(duì)其序列化后則是“深拷貝”。)

序列化:將結(jié)構(gòu)數(shù)據(jù)或者對(duì)象轉(zhuǎn)換成能夠用于存儲(chǔ)和傳輸?shù)母袷健?/p>

反序列化:在其他的計(jì)算環(huán)境中,將序列化后的數(shù)據(jù)還原為數(shù)據(jù)結(jié)構(gòu)和對(duì)象。

從“序列化”字面上的理解,似乎使用C語(yǔ)言中的struct結(jié)構(gòu)體就可以實(shí)現(xiàn)序列化的功能:將結(jié)構(gòu)數(shù)據(jù)填充到定義好的結(jié)構(gòu)體中的對(duì)應(yīng)字段即可,接收方再對(duì)結(jié)構(gòu)體進(jìn)行解析。

在單機(jī)的不同進(jìn)程間通信時(shí),使用struct結(jié)構(gòu)體這種方法實(shí)現(xiàn)“序列化”和“反序列化”的功能問(wèn)題不大,但是,在網(wǎng)絡(luò)編程中,即面向網(wǎng)絡(luò)中不同主機(jī)間的通信時(shí),則不能使用struct結(jié)構(gòu)體,原因在于:

(1)跨語(yǔ)言平臺(tái),例如發(fā)送方是用C語(yǔ)言編寫的程序,接收方是用Java語(yǔ)言編寫的程序,不同語(yǔ)言的struct結(jié)構(gòu)體定義方式不同,不能直接解析;

(2)struct結(jié)構(gòu)體存在 內(nèi)存對(duì)齊 和 CPU不兼容的問(wèn)題。

因此,在網(wǎng)絡(luò)編程中,實(shí)現(xiàn)“序列化”和“反序列化”功能需要使用通用的組件,如 Json、XML、protobuf 等。

1.2 protobuf的優(yōu)缺點(diǎn):

1.2.1 優(yōu)點(diǎn):

① 性能高效:

與XML相比,protobuf更小(3 ~ 10倍)、更快(20 ~ 100倍)、更為簡(jiǎn)單。

② 語(yǔ)言無(wú)關(guān)、平臺(tái)無(wú)關(guān):

protobuf支持Java、C++、Python等多種語(yǔ)言,支持多個(gè)平臺(tái)。

③ 擴(kuò)展性、兼容性強(qiáng):

只需要使用protobuf對(duì)結(jié)構(gòu)數(shù)據(jù)進(jìn)行一次描述,即可從各種數(shù)據(jù)流中讀取結(jié)構(gòu)數(shù)據(jù),更新數(shù)據(jù)結(jié)構(gòu)時(shí)不會(huì)破壞原有的程序。

Protobuf與XML、Json的性能對(duì)比:

測(cè)試10萬(wàn)次序列化:

圖片

測(cè)試10萬(wàn)次反序列化:

圖片

1.2.2 缺點(diǎn):

① 自解釋性較差,數(shù)據(jù)存儲(chǔ)格式為二進(jìn)制,需要通過(guò) .proto 文件才能了解到內(nèi)部的數(shù)據(jù)結(jié)構(gòu);

② 不適合用來(lái)對(duì) 基于文本的標(biāo)記文檔(如HTML) 建模。

1.3 protobuf中的數(shù)據(jù)類型限定修飾符:

protobuf 2 中有三種數(shù)據(jù)類型限定修飾符:

required, optional, repeated

required表示字段必選,optional表示字段可選,repeated表示一個(gè)數(shù)組類型。

其中, required 和 optional 已在 proto3 棄用了。

1.4 protobuf中常用的數(shù)據(jù)類型:

bool, 布爾類型

double, 64位浮點(diǎn)數(shù)
float, 32位浮點(diǎn)數(shù)

int32, 32位整數(shù)
int64, 64位整數(shù)
uint64, 64位無(wú)符號(hào)整數(shù)
sint32, 32位整數(shù),處理負(fù)數(shù)效率更高
sint64, 64位整數(shù),處理負(fù)數(shù)效率更高

string, 只能處理ASCII字符
bytes, 用于處理多字節(jié)的語(yǔ)言字符
enum, 枚舉類型

二、protobuf的使用流程:

下載protobuf壓縮包后,解壓、配置、編譯、安裝,即可使用 protoc 命令 查看Linux中是否安裝成功:

[root@linux] protoc --version
libprotoc 3.15.8

使用protobuf時(shí),需要先根據(jù)應(yīng)用需求編寫 .proto 文件 定義消息體格式,例如:

syntax = "proto3";
package tutorial;

option optimize_for = LITE_RUNTIME;

message Person {
int32 id = 1;
repeated string name = 2;
}

其中,syntax 關(guān)鍵字表示使用的protobuf的版本,如不指定則默認(rèn)使用 "proto2";package關(guān)鍵字 表示“包”,生成目標(biāo)語(yǔ)言文件后對(duì)應(yīng)C++中的namespace命名空間,用于防止不同的消息類型間的命名沖突。

(syntax單詞字面含義:句法,句法規(guī)則,語(yǔ)構(gòu))

然后使用 protobuf編譯器(protoc命令)將編寫好的 .proto 文件生成 目標(biāo)語(yǔ)言文件(例如目標(biāo)語(yǔ)言是C++,則會(huì)生成 .cc 和 .h 文件),例如:

[root@linux] protoc -I=$SRC_DIR $SRC_DIR/xxx.proto --cpp_out=$DST_DIR

其中:

**SRC_DIR 表示 .proto文件所在的源目錄;**DST_DIR 表示生成目標(biāo)語(yǔ)言代碼的目標(biāo)目錄;xxx.proto 表示要對(duì)哪個(gè).proto文件進(jìn)行解析;--cpp_out 表示生成C++代碼。

編譯完成后,將會(huì)在目標(biāo)目錄中生成 xxx.pb.h 和 pb.cc, 文件,將其引入到我們的C++工程中即可實(shí)現(xiàn)使用protobuf進(jìn)行序列化:

在C++源文件中包含 xxx.pb.h 頭文件,在g++編譯時(shí)鏈接 xxx.pb.cc源文件即可:

g++ main_test.cpp pb.cc, -o main_test -lprotobuf

三、C++使用protobuf實(shí)現(xiàn)序列化的示例:

在protobuf源碼中的 /examples 目錄下有官方提供的protobuf使用示例:addressbook.proto

參考官方示例實(shí)現(xiàn)C++使用protobuf進(jìn)行序列化和反序列化:

addressbook.proto :

syntax = "proto3";
package tutorial;

option optimize_for = LITE_RUNTIME;

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 phones = 4;
}

生成的addressbook.pb.h 文件內(nèi)容摘要:

namespace tutorial {
class Person;
class Person_PhoneNumber;
};

class Person_PhoneNumber : public MessageLite {
public:
Person_PhoneNumber();
virtual ~Person_PhoneNumber();
public:
//string number = 1;
void clear_number();
const string& number() const;
void set_number(const string& value);

//int32 id = 2;
void clear_id();
int32 id() const;
void set_id(int32 value);

//string email = 3;
//...
};

add_person.cpp :

#include
#include
#include
#include "pbs/addressbook.pb.h"
using namespace std;

void serialize_process() {
cout << "serialize_process" << endl;
tutorial::Person person;
person.set_name("Obama");
person.set_id(1234);
person.set_email("[email protected]");

tutorial::Person::PhoneNumber *phone1 = person.add_phones();
phone1->set_number("110");
phone1->set_type(tutorial::Person::MOBILE);

tutorial::Person::PhoneNumber *phone2 = person.add_phones();
phone2->set_number("119");
phone2->set_type(tutorial::Person::HOME);

fstream output("person_file", ios::out | ios::trunc | ios::binary);

if( !person.SerializeToOstream(&output) ) {
cout << "Fail to SerializeToOstream." << endl;
}

cout << "person.ByteSizeLong() : " << person.ByteSizLong() << endl;
}

void parse_process() {
cout << "parse_process" << endl;
tutorial::Person result;
fstream input("person_file", ios::in | ios::binary);

if(!result.ParseFromIstream(&input)) {
cout << "Fail to ParseFromIstream." << endl;
}

cout << result.name() << endl;
cout << result.id() << endl;
cout << Buy and Sell Domain Names() << endl;
for(int i = 0; i < result.phones_size(); ++i) {
const tutorial::Person::PhoneNumber &person_phone = result.phones(i);

switch(person_phone.type()) {
case tutorial::Person::MOBILE :
cout << "MOBILE phone : ";
break;
case tutorial::Person::HOME :
cout << "HOME phone : ";
break;
case tutorial::Person::WORK :
cout << "WORK phone : ";
break;
default:
cout << "phone type err." << endl;
}
cout << person_phone.number() << endl;
}
}

int main(int argc, char *argv[]) {
serialize_process();
parse_process();

google::protobuf::ShutdownProtobufLibrary(); //刪除所有已分配的內(nèi)存(Protobuf使用的堆內(nèi)存)
return 0;
}

輸出結(jié)果:

[serialize_process]
person.ByteSizeLong() : 39
[parse_process]
Obama
1234
[email protected]
MOBILE phone : 110
HOME phone : 119

3.1 protobuf提供的序列化和反序列化的API接口函數(shù):

class MessageLite {
public:
//序列化:
bool SerializeToOstream(ostream* output) const;
bool SerializeToArray(void *data, int size) const;
bool SerializeToString(string* output) const;

//反序列化:
bool ParseFromIstream(istream* input);
bool ParseFromArray(const void* data, int size);
bool ParseFromString(const string& data);
};

三種序列化的方法沒(méi)有本質(zhì)上的區(qū)別,只是序列化后輸出的格式不同,可以供不同的應(yīng)用場(chǎng)景使用。

序列化的API函數(shù)均為const成員函數(shù),因?yàn)樾蛄谢粫?huì)改變類對(duì)象的內(nèi)容, 而是將序列化的結(jié)果保存到函數(shù)入?yún)⒅付ǖ牡刂分小?/p>

3.2 .proto文件中的 option 選項(xiàng):

.proto文件中的option選項(xiàng)用于配置protobuf編譯后生成目標(biāo)語(yǔ)言文件中的代碼量,可設(shè)置為 SPEED, CODE_SIZE, LITE_RUNTIME 三種。

默認(rèn)option選項(xiàng)為 SPEED,常用的選項(xiàng)為 LITE_RUNTIME。

三者的區(qū)別在于:

① SPEED(默認(rèn)值):表示生成的代碼運(yùn)行效率高,但是由此生成的代碼編譯后會(huì)占用更多的空間。② CODE_SIZE:與SPEED恰恰相反,代碼運(yùn)行效率較低,但是由此生成的代碼編譯后會(huì)占用更少的空間,
通常用于資源有限的平臺(tái),如Mobile。③ LITE_RUNTIME:生成的代碼執(zhí)行效率高,同時(shí)生成代碼編譯后的所占用的空間也非常少。這是以犧牲Protobuf提供的反射功能為代價(jià)的。因此我們?cè)贑++中鏈接Protobuf庫(kù)時(shí)僅需鏈接libprotobuf-lite,而非protobuf。

SPEED 和 LITE_RUNTIME相比,在于調(diào)試級(jí)別上,例如 msg.SerializeToString(&str); 在 SPEED 模式下會(huì)利用反射機(jī)制打印出詳細(xì)字段和字段值,但是 LITE_RUNTIME 則僅僅打印字段值組成的字符串。

因此:可以在調(diào)試階段使用 SPEED 模式,而上線以后提升性能使用 LITE_RUNTIME 模式優(yōu)化。

最直觀的區(qū)別是使用三種不同的 option 選項(xiàng)時(shí),編譯后產(chǎn)生的 .pb.h 中自定義的類所繼承的 protobuf類不同:

//1. SPEED模式:(自定義的類繼承自 Message 類)
// .proto 文件:
option optimize_for = SPEED;
// .pb.h 文件:
class Person : public ::PROTOBUF_NAMESPACE_ID::Message {};

//2. CODE_SIZE模式:(自定義的類繼承自 Message 類)
// .proto 文件:
option optimize_for = CODE_SIZE;
// .pb.h 文件:
class Person : public ::PROTOBUF_NAMESPACE_ID::Message {};

//3. LITE_RUNTIME模式:(自定義的類繼承自 MessageLite 類)
// .proto 文件:
option optimize_for = LITE_RUNTIME;
// .pb.h 文件:
class Person : public ::PROTOBUF_NAMESPACE_ID::MessageLite {};

四、protobuf的編碼和存儲(chǔ)方式:

① protobuf 將消息里的每個(gè)字段進(jìn)行編碼后,再利用TLV或者TV的方式進(jìn)行數(shù)據(jù)存儲(chǔ);

② protobuf 對(duì)于不同類型的數(shù)據(jù)會(huì)使用不同的編碼和存儲(chǔ)方式;

③ protobuf 的編碼和存儲(chǔ)方式是其性能優(yōu)越、數(shù)據(jù)體積小的原因。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 存儲(chǔ)
    +關(guān)注

    關(guān)注

    13

    文章

    4359

    瀏覽量

    86203
  • 編碼
    +關(guān)注

    關(guān)注

    6

    文章

    958

    瀏覽量

    54965
  • 函數(shù)指針
    +關(guān)注

    關(guān)注

    2

    文章

    56

    瀏覽量

    3835
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【LeMaker Guitar試用體驗(yàn)】8.Lemuntu系統(tǒng)中編譯protobuf源代碼和簡(jiǎn)單示例

    本帖最后由 xble 于 2016-2-17 11:42 編輯 protobuf是什么東東?http://blog.csdn.net/menuconfig/article/details
    發(fā)表于 02-17 11:42

    存儲(chǔ)器的編碼方法

    第一存儲(chǔ)體時(shí),會(huì)出現(xiàn)訪問(wèn)阻塞的現(xiàn)象,故需要通過(guò)編碼以及解碼重建數(shù)據(jù)的方式同時(shí)為多個(gè)訪問(wèn)提供數(shù)據(jù)。其中,編碼的時(shí)機(jī)應(yīng)當(dāng)為所選的操作時(shí)機(jī)。104、獲取上述第二
    發(fā)表于 11-15 15:44

    Go Protobuf資源的可讀化 ,看完你就懂了

    Go Protobuf資源的可讀化 ,看完你就懂了
    發(fā)表于 06-15 09:08

    利用protobuf通信原理

    protobuf打包數(shù)據(jù)并通過(guò)串口發(fā)出的形式,即發(fā)送端編碼數(shù)據(jù)并序列化成數(shù)組通過(guò)串口發(fā)出,接收端接收到一幀數(shù)據(jù),進(jìn)行解碼并解析數(shù)據(jù)。二、...
    發(fā)表于 08-20 07:25

    什么是protobuf?怎么使用?

    什么是protobuf-c 之前的文章:《Protobuf:一種更小、更快、更高效的協(xié)議》詳細(xì)介紹了protobufprotobuf-c。這里再簡(jiǎn)單提一下:Protocol Buff
    發(fā)表于 12-16 06:03

    基于加密技術(shù)和編碼技術(shù)的存儲(chǔ)分割編碼技術(shù)

    針對(duì)移動(dòng)終端頻繁更新數(shù)據(jù)效率低、安全性不高的問(wèn)題,提出一種基于加密技術(shù)和編碼技術(shù)的存儲(chǔ)分割編碼技術(shù)。首先,將移動(dòng)終端的數(shù)據(jù)進(jìn)行等分分割后存儲(chǔ)在云端,通過(guò)
    發(fā)表于 12-20 16:23 ?0次下載
    基于加密技術(shù)和<b class='flag-5'>編碼</b>技術(shù)的<b class='flag-5'>存儲(chǔ)</b>分割<b class='flag-5'>編碼</b>技術(shù)

    protobuf是什么?protobuf有什么作用支持什么數(shù)據(jù)類型?

    protobuf是google旗下的一款平臺(tái)無(wú)關(guān),語(yǔ)言無(wú)關(guān),可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)格式。所以很適合用做數(shù)據(jù)存儲(chǔ)和作為不同應(yīng)用,不同語(yǔ)言之間相互通信的數(shù)據(jù)交換格式,只要實(shí)現(xiàn)相同的協(xié)議格式即同一
    發(fā)表于 09-27 16:29 ?3次下載

    深入剖析ProtoBuf原理與工程實(shí)踐

    ProtoBuf 作為一種跨平臺(tái)、語(yǔ)言無(wú)關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)的方法,已廣泛應(yīng)用于網(wǎng)絡(luò)數(shù)據(jù)交換及存儲(chǔ)。隨著互聯(lián)網(wǎng)的發(fā)展,系統(tǒng)的異構(gòu)性會(huì)愈發(fā)突出,跨語(yǔ)言的需求會(huì)愈加明顯,同時(shí) gRPC 也大有取代
    的頭像 發(fā)表于 11-16 09:15 ?1644次閱讀
    深入剖析<b class='flag-5'>ProtoBuf</b>原理與工程實(shí)踐

    Intellij IDEA插件idea-plugin-protobuf

    ./oschina_soft/idea-plugin-protobuf.zip
    發(fā)表于 05-18 11:09 ?2次下載
    Intellij IDEA插件idea-plugin-<b class='flag-5'>protobuf</b>

    結(jié)構(gòu)化數(shù)據(jù):ProtoBuf試用與JSON的比較

    XML、JSON 也可以用來(lái)存儲(chǔ)此類結(jié)構(gòu)化數(shù)據(jù),但是使用ProtoBuf表示的數(shù)據(jù)能更加高效,并且將數(shù)據(jù)壓縮得更小。
    發(fā)表于 03-08 15:43 ?1922次閱讀

    C語(yǔ)言動(dòng)態(tài)存儲(chǔ)方式與靜態(tài)存儲(chǔ)方式

    靜態(tài)存儲(chǔ)方式是指在程序運(yùn)行期間由系統(tǒng)分配固定的存儲(chǔ)空間的方式;動(dòng)態(tài)存儲(chǔ)方式是在程序運(yùn)行期間根據(jù)需
    的頭像 發(fā)表于 03-10 14:34 ?2084次閱讀

    protobuf怎么發(fā)現(xiàn)的?

    最近我們?cè)陧?xiàng)目中,通過(guò)使用 protobuf 格式作為存儲(chǔ)數(shù)據(jù)的一個(gè)載體。一個(gè)不小心就給自己埋了個(gè)大坑,還是過(guò)了好久才發(fā)現(xiàn)。 protobuf 簡(jiǎn)介 protobuf 全名叫 Prot
    的頭像 發(fā)表于 09-25 11:26 ?545次閱讀

    視頻監(jiān)控?cái)?shù)據(jù)有哪些存儲(chǔ)方式?哪種存儲(chǔ)方式最優(yōu)?

    視頻監(jiān)控?cái)?shù)據(jù)有哪些存儲(chǔ)方式?哪種存儲(chǔ)方式最優(yōu)? 隨著社會(huì)的發(fā)展,視頻監(jiān)控技術(shù)已經(jīng)成為城市安全管理中不可缺少的一部分。隨之而來(lái)的是海量的視頻監(jiān)控?cái)?shù)據(jù),如何合理地保存這些數(shù)據(jù)成為了一個(gè)重要
    的頭像 發(fā)表于 10-26 11:16 ?3507次閱讀

    ARM中的編碼方式與尋址方式有何不同?

    ARM中的編指方式與尋址方式有何不同? ARM處理器是一種廣泛應(yīng)用的微處理器架構(gòu),被廣泛用于移動(dòng)設(shè)備、嵌入式設(shè)備以及智能家居等領(lǐng)域。在ARM架構(gòu)中,編碼方式和尋址
    的頭像 發(fā)表于 01-29 18:10 ?770次閱讀

    什么是編碼方式、數(shù)據(jù)質(zhì)量和傳輸需求

    信息從一種形式或格式轉(zhuǎn)換為另一種形式或格式的過(guò)程。在數(shù)據(jù)傳輸和存儲(chǔ)中,編碼方式的選擇直接影響數(shù)據(jù)的可讀性、可壓縮性、安全性以及傳輸效率。 常見編碼
    的頭像 發(fā)表于 01-10 13:21 ?139次閱讀