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

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

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

什么是序列化 為什么要序列化

麥辣雞腿堡 ? 來源:古月居 ? 作者:古月居 ? 2023-09-14 17:22 ? 次閱讀

什么是序列化?

“序列化”(Serialization )的意思是將一個對象轉(zhuǎn)化為字節(jié)流。

這里說的對象可以理解為“面向?qū)ο蟆崩锏哪莻€對象,具體的就是存儲在內(nèi)存中的對象數(shù)據(jù)。

與之相反的過程是“反序列化”(Deserialization )。

雖然掛著機(jī)器人的羊頭,但是后面的介紹全部是計算機(jī)知識,跟機(jī)器人一丁點關(guān)系都沒有,序列化就是一個純粹的計算機(jī)概念。

序列化的英文Serialize就有把一個東西變成一串連續(xù)的東西之意。

形象的描述,數(shù)據(jù)對象是一團(tuán)面,序列化就是將面團(tuán)拉成一根面條,反序列化就將面條捏回面團(tuán)。

另一個形象的類比是我們在對話或者打電話時,一個人的思想轉(zhuǎn)換成一維的語音,然后在另一個人的頭腦里重新變成結(jié)構(gòu)化的思想,這也是一種序列化。

圖片

面對序列化,很多人心中可能會有很多疑問。

首先,為什么要序列化?或者更具體的說,既然對象的信息本來就是以字節(jié)的形式儲存在內(nèi)存中,那為什么要多此一舉把一些字節(jié)數(shù)據(jù)轉(zhuǎn)換成另一種形式的、一維的、連續(xù)的字節(jié)數(shù)據(jù)呢?

如果我們的程序在內(nèi)存中存儲了一個數(shù)字,比如25。那要怎么傳遞25這個數(shù)字給別的程序節(jié)點或者把這個數(shù)字永久存儲起來呢?

很簡單,直接傳遞25這個數(shù)字(的字節(jié)表示,即0X19,當(dāng)然最終會變成二進(jìn)制表示11001以高低電平傳輸存儲)或者直接把這個數(shù)字(的字節(jié)表示)寫進(jìn)硬盤里即可。

所以,對于本來就是連續(xù)的、一維的、一連串的數(shù)據(jù)(例如字符串),序列化并不需要做太多東西,其本質(zhì)是就是由內(nèi)存向其它地方拷貝數(shù)據(jù)而已。

所以,如果你在一個序列化庫里看到memcpy函數(shù)不用覺得奇怪,因為你知道序列化最底層不過就是在操作內(nèi)存數(shù)據(jù)而已(還有些庫使用了流的ostream.rdbuf()-》sputn函數(shù))。

可是實際程序操作的對象很少是這么簡單的形式,大多數(shù)時候我們面對的是包含不同數(shù)據(jù)類型(int、double、string)的復(fù)雜數(shù)據(jù)結(jié)構(gòu)(比如vector、list),它們很可能在內(nèi)存中是不連續(xù)存儲的而是分散在各處。比如ROS的很多消息都包含向量。

數(shù)據(jù)中還有各種指針和引用。而且,如果數(shù)據(jù)要在運(yùn)行于不同架構(gòu)的計算機(jī)之上的、由不同編程語言所編寫的節(jié)點程序之間傳遞,那問題就更復(fù)雜了,它們的字節(jié)順序endianness規(guī)定有可能不一樣,基本數(shù)據(jù)類型(比如int)的長度也不一樣(有的int是4個字節(jié)、有的是8個字節(jié))。

這些都不是通過簡單地、原封不動地復(fù)制粘貼原始數(shù)據(jù)就能解決的。這時候就需要序列化和反序列化了。

所以在程序之間需要通信時(ROS恰好就是這種情況),或者希望保存程序的中間運(yùn)算結(jié)果時,序列化就登場了。

另外,在某種程度上,序列化還起到統(tǒng)一標(biāo)準(zhǔn)的作用。

我們把被序列化的東西叫object(對象),它可以是任意的數(shù)據(jù)結(jié)構(gòu)或者對象:結(jié)構(gòu)體、數(shù)組、類的實例等等。

把序列化后得到的東西叫archive,它既可以是人類可讀的文本形式,也可以是二進(jìn)制形式。

前者比如JSON和XML,這兩個是網(wǎng)絡(luò)應(yīng)用里最常用的序列化格式,通過記事本就能打開閱讀;

后者就是原始的二進(jìn)制文件,比如后綴名是bin的文件,人類是沒辦法直接閱讀一堆的0101或者0XC9D23E72的。

序列化算是一個比較常用的功能,所以大多數(shù)編程語言(比如C++、Python、Java等)都會附帶用于序列化的庫,不需要你再去造輪子。

以C++為例,雖然標(biāo)準(zhǔn)STL庫沒有提供序列化功能,但是第三方庫Boost提供了[ 2
]谷歌的protobuf也是一個序列化庫,還有Fast-CDR,以及不太知名的Cereal,Java自帶序列化函數(shù),python可以使用第三方的pickle模塊實現(xiàn)。

總之,序列化沒有什么神秘的,用戶可以看看這些開源的序列化庫代碼,或者自己寫個小程序試試簡單數(shù)據(jù)的序列化,例如這個例子,或者這個,有助于更好地理解ROS中的實現(xiàn)。

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

    關(guān)注

    8

    文章

    6762

    瀏覽量

    88622
  • 編程語言
    +關(guān)注

    關(guān)注

    10

    文章

    1921

    瀏覽量

    34507
  • ROS
    ROS
    +關(guān)注

    關(guān)注

    1

    文章

    276

    瀏覽量

    16920
收藏 人收藏

    評論

    相關(guān)推薦

    如何使用Serde進(jìn)行序列化和反序列化

    Serde 是一個用于序列化和反序列化 Rust 數(shù)據(jù)結(jié)構(gòu)的庫。它支持 JSON、BSON、YAML 等多種格式,并且可以自定義序列化和反序列化方式。Serde 的特點是代碼簡潔、易于
    的頭像 發(fā)表于 09-30 17:09 ?1218次閱讀

    Java序列化的機(jī)制和原理

    本文講解了Java序列化的機(jī)制和原理。從文中你可以了解如何序列化一個對象,什么時候需要序列化以及Java序列化的算法。AD:WOT2014課程推薦:實戰(zhàn)MSA:用開源軟件搭建微服務(wù)系統(tǒng)
    發(fā)表于 07-10 07:27

    c語言序列化和反序列化有何區(qū)別

    這里寫自定義目錄標(biāo)題c語言序列化和反序列化tplut.htplut.c測試代碼參考c語言序列化和反序列化網(wǎng)絡(luò)調(diào)用,數(shù)據(jù)傳輸都需要把數(shù)據(jù)序列化
    發(fā)表于 07-14 07:32

    關(guān)于c語言序列化和反序列化的知識點看完你就懂了

    關(guān)于c語言序列和反序列化的知識點你就懂了
    發(fā)表于 10-15 08:47

    SpringMVC JSON框架的自定義序列化與反序列化

    ?StringCodec是fastJson默認(rèn)的String類型的反序列化邏輯類,里面處理的類型有String、StringBuffer、StringBuilder等,還有各種的集合、數(shù)組結(jié)構(gòu),涉及
    發(fā)表于 10-10 16:02

    序列化的網(wǎng)絡(luò)流量分類算法

    針對傳統(tǒng)基于端口和有效負(fù)載的網(wǎng)絡(luò)流量分類算法識別率低分類算法復(fù)雜等問題,在分析了網(wǎng)絡(luò)流量性質(zhì)的基礎(chǔ)上提出流序列化方法。它將網(wǎng)絡(luò)流分解成多個流原子#通過提取序列化網(wǎng)絡(luò)
    發(fā)表于 05-16 17:29 ?23次下載
    流<b class='flag-5'>序列化</b>的網(wǎng)絡(luò)流量分類算法

    理解PHP反序列化漏洞

    理解PHP反序列化漏洞
    發(fā)表于 09-07 11:03 ?7次下載
    理解PHP反<b class='flag-5'>序列化</b>漏洞

    java序列化和反序列化范例和JDK類庫中的序列化API

    一、序列化和反序列化的概念 把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化。 把字節(jié)序列恢復(fù)為對象的過程稱為對象的反
    發(fā)表于 09-27 10:13 ?6次下載

    static屬性為什么不會被序列化

    實現(xiàn)序列化和反序列化為什么實現(xiàn)Serializable接口?
    的頭像 發(fā)表于 07-15 11:03 ?1702次閱讀

    C#實現(xiàn)對象序列化的三種方式是什么

    很多小伙伴一提到序列化,都會想到二進(jìn)制序列化,但其實序列化并不僅僅只是二進(jìn)制序列化,我們常說的對象序列化有三種方式,分別是二進(jìn)制
    的頭像 發(fā)表于 02-22 16:11 ?1064次閱讀
    C#實現(xiàn)對象<b class='flag-5'>序列化</b>的三種方式是什么

    python序列化對象

    序列化對象:將對象轉(zhuǎn)換為可以存儲或傳輸?shù)男问健? (1) 用于存儲:將對象的字節(jié)序列存儲到文件中,程序退出后不會消失,便于后續(xù)使用。
    的頭像 發(fā)表于 03-10 09:57 ?2296次閱讀

    ROS中的序列化實現(xiàn)

    理解了序列化,再回到ROS。我們發(fā)現(xiàn),ROS沒有采用第三方的序列化工具,而是選擇自己實現(xiàn),代碼在roscpp_core項目下的roscpp_serialization中,見下圖。這個功能涉及的代碼量
    的頭像 發(fā)表于 09-14 17:26 ?848次閱讀

    如何用C語言進(jìn)行json的序列化和反序列化

    json是目前最為流行的文本數(shù)據(jù)傳輸格式,特別是在網(wǎng)絡(luò)通信上廣泛應(yīng)用,隨著物聯(lián)網(wǎng)的興起,在嵌入式設(shè)備上,也需要開始使用json進(jìn)行數(shù)據(jù)傳輸,那么,如何快速簡潔地用C語言進(jìn)行json的序列化和反序列化
    的頭像 發(fā)表于 10-07 11:05 ?1322次閱讀

    Java序列化怎么使用

    轉(zhuǎn)換方式就叫做序列化。將文件或者網(wǎng)絡(luò)傳輸中得到的 byte[] 數(shù)組轉(zhuǎn)換為 java 對象就叫做反序列化。 怎么使用 如果一個 Java 對象要能被序列化,必須實現(xiàn)一個特殊
    的頭像 發(fā)表于 10-10 14:19 ?394次閱讀

    什么時候需要Boost序列化

    程序開發(fā)中,序列化是經(jīng)常需要用到的。像一些相對高級語言,比如JAVA, C#都已經(jīng)很好的支持了序列化,那么C++呢?當(dāng)然一個比較好的選擇就是用Boost,這個號稱C++準(zhǔn)標(biāo)準(zhǔn)庫的東西。 什么時候需要
    的頭像 發(fā)表于 11-10 10:14 ?377次閱讀