什么是序列化?
“序列化”(Serialization )的意思是將一個(gè)對(duì)象轉(zhuǎn)化為字節(jié)流。
這里說(shuō)的對(duì)象可以理解為“面向?qū)ο蟆崩锏哪莻€(gè)對(duì)象,具體的就是存儲(chǔ)在內(nèi)存中的對(duì)象數(shù)據(jù)。
與之相反的過(guò)程是“反序列化”(Deserialization )。
雖然掛著機(jī)器人的羊頭,但是后面的介紹全部是計(jì)算機(jī)知識(shí),跟機(jī)器人一丁點(diǎn)關(guān)系都沒有,序列化就是一個(gè)純粹的計(jì)算機(jī)概念。
序列化的英文Serialize就有把一個(gè)東西變成一串連續(xù)的東西之意。
形象的描述,數(shù)據(jù)對(duì)象是一團(tuán)面,序列化就是將面團(tuán)拉成一根面條,反序列化就將面條捏回面團(tuán)。
另一個(gè)形象的類比是我們?cè)趯?duì)話或者打電話時(shí),一個(gè)人的思想轉(zhuǎn)換成一維的語(yǔ)音,然后在另一個(gè)人的頭腦里重新變成結(jié)構(gòu)化的思想,這也是一種序列化。
面對(duì)序列化,很多人心中可能會(huì)有很多疑問。
首先,為什么要序列化?或者更具體的說(shuō),既然對(duì)象的信息本來(lái)就是以字節(jié)的形式儲(chǔ)存在內(nèi)存中,那為什么要多此一舉把一些字節(jié)數(shù)據(jù)轉(zhuǎn)換成另一種形式的、一維的、連續(xù)的字節(jié)數(shù)據(jù)呢?
如果我們的程序在內(nèi)存中存儲(chǔ)了一個(gè)數(shù)字,比如25。那要怎么傳遞25這個(gè)數(shù)字給別的程序節(jié)點(diǎn)或者把這個(gè)數(shù)字永久存儲(chǔ)起來(lái)呢?
很簡(jiǎn)單,直接傳遞25這個(gè)數(shù)字(的字節(jié)表示,即0X19,當(dāng)然最終會(huì)變成二進(jìn)制表示11001以高低電平傳輸存儲(chǔ))或者直接把這個(gè)數(shù)字(的字節(jié)表示)寫進(jìn)硬盤里即可。
所以,對(duì)于本來(lái)就是連續(xù)的、一維的、一連串的數(shù)據(jù)(例如字符串),序列化并不需要做太多東西,其本質(zhì)是就是由內(nèi)存向其它地方拷貝數(shù)據(jù)而已。
所以,如果你在一個(gè)序列化庫(kù)里看到memcpy函數(shù)不用覺得奇怪,因?yàn)槟阒佬蛄谢畹讓硬贿^(guò)就是在操作內(nèi)存數(shù)據(jù)而已(還有些庫(kù)使用了流的ostream.rdbuf()-》sputn函數(shù))。
可是實(shí)際程序操作的對(duì)象很少是這么簡(jiǎn)單的形式,大多數(shù)時(shí)候我們面對(duì)的是包含不同數(shù)據(jù)類型(int、double、string)的復(fù)雜數(shù)據(jù)結(jié)構(gòu)(比如vector、list),它們很可能在內(nèi)存中是不連續(xù)存儲(chǔ)的而是分散在各處。比如ROS的很多消息都包含向量。
數(shù)據(jù)中還有各種指針和引用。而且,如果數(shù)據(jù)要在運(yùn)行于不同架構(gòu)的計(jì)算機(jī)之上的、由不同編程語(yǔ)言所編寫的節(jié)點(diǎn)程序之間傳遞,那問題就更復(fù)雜了,它們的字節(jié)順序endianness規(guī)定有可能不一樣,基本數(shù)據(jù)類型(比如int)的長(zhǎng)度也不一樣(有的int是4個(gè)字節(jié)、有的是8個(gè)字節(jié))。
這些都不是通過(guò)簡(jiǎn)單地、原封不動(dòng)地復(fù)制粘貼原始數(shù)據(jù)就能解決的。這時(shí)候就需要序列化和反序列化了。
所以在程序之間需要通信時(shí)(ROS恰好就是這種情況),或者希望保存程序的中間運(yùn)算結(jié)果時(shí),序列化就登場(chǎng)了。
另外,在某種程度上,序列化還起到統(tǒng)一標(biāo)準(zhǔn)的作用。
我們把被序列化的東西叫object(對(duì)象),它可以是任意的數(shù)據(jù)結(jié)構(gòu)或者對(duì)象:結(jié)構(gòu)體、數(shù)組、類的實(shí)例等等。
把序列化后得到的東西叫archive,它既可以是人類可讀的文本形式,也可以是二進(jìn)制形式。
前者比如JSON和XML,這兩個(gè)是網(wǎng)絡(luò)應(yīng)用里最常用的序列化格式,通過(guò)記事本就能打開閱讀;
后者就是原始的二進(jìn)制文件,比如后綴名是bin的文件,人類是沒辦法直接閱讀一堆的0101或者0XC9D23E72的。
序列化算是一個(gè)比較常用的功能,所以大多數(shù)編程語(yǔ)言(比如C++、Python、Java等)都會(huì)附帶用于序列化的庫(kù),不需要你再去造輪子。
以C++為例,雖然標(biāo)準(zhǔn)STL庫(kù)沒有提供序列化功能,但是第三方庫(kù)Boost提供了[ 2
]谷歌的protobuf也是一個(gè)序列化庫(kù),還有Fast-CDR,以及不太知名的Cereal,Java自帶序列化函數(shù),python可以使用第三方的pickle模塊實(shí)現(xiàn)。
總之,序列化沒有什么神秘的,用戶可以看看這些開源的序列化庫(kù)代碼,或者自己寫個(gè)小程序試試簡(jiǎn)單數(shù)據(jù)的序列化,例如這個(gè)例子,或者這個(gè),有助于更好地理解ROS中的實(shí)現(xiàn)。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7134瀏覽量
89391 -
編程語(yǔ)言
+關(guān)注
關(guān)注
10文章
1950瀏覽量
34902 -
ROS
+關(guān)注
關(guān)注
1文章
280瀏覽量
17056
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論