序列化、反序列化與jsoncpp學習

json是序列化與反序列化的一種方式。

1. 什麼叫序列化和反序列化?用途是什麼?

把對象轉換爲字節序列的過程稱爲對象的序列化。 
把字節序列恢復爲對象的過程稱爲對象的反序列化。 
1) 把對象的字節序列永久地保存到硬盤上,通常存放在一個文件中; 
2) 在網絡上傳送對象的字節序列。 
對象的序列化主要有兩種用途: 
  在很多應用中,需要對某些對象進行序列化,讓它們離開內存空間,入住物理硬盤,以便長期保存。比如最常見的是Web服務器中的Session對象,當有 10萬用戶併發訪問,就有可能出現10萬個Session對象,內存可能吃不消,於是Web容器就會把一些seesion先序列化到硬盤中,等要用了,再把保存在硬盤中的對象還原到內存中。 
  當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個對象轉換爲字節序列,才能在網絡上傳送;接收方收到對象後則需要把字節序列再恢復爲相應對象進行某些操作。 
以上引用自: http://www.cnblogs.com/xdp-gacl/p/3777987.html 《Java基礎學習總結——Java對象的序列化和反序列化》 <孤傲蒼狼>

2. 如果不使用序列化,直接在發送端和接收端發送對象會產生什麼問題?

假如發送端和接收端都使用c++編寫,發送端給接收端發送一個結構體,對象如下:

struct args
{
    long arg1;
    long arg2;
}
args arg;
arg.arg1 = 1;
arg.arg2 = 2;
Writen(sockfd,&args,sizeof(args));    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

接收端代碼爲:

struct args arg;
Readn(sockfd,&arggs,sizeof(args))
  • 1
  • 2
  • 1
  • 2

這樣寫會有什麼問題呢?其實以上代碼存在三個潛在的問題: 
(1)不同的實現以不同的格式存儲二進制數。最常見的便是不同的字節序問題。有的機器使用大端字節序有的機器使用小端字節序。 
(2)不同的實現在存儲相同的C數據類型上可能存在差異。舉例來說,大多數32位unix系統使用32位表示長整數,而64位系統卻典型地使用64位來表示同樣的數據類型。對於short、int或long等整數類型,它們各自的大小沒有確定的保證。 
(3)不同的實現給結構體打包的方式存在差異,取決於各種數據類型所用的位數以及機器的對齊限制。 
因此,穿越套接字傳送二進制結構絕不是明智的。 
以上參考自《Unix網絡編程卷1》的5.18節《數據格式》 
解決這種數據格式問題的一個方法就是顯示定義所支持數據類型的二進制格式(位數、大端或小端字節序),並以這種的格式在客戶與服務器之間傳送所有數據(序列化的工作),而序列化統統幫我們做好了這些工作。

3. 常用的序列化與反序列化協議

當下比較流行的序列化協議,包括XML、JSON、Protobuf、Thrift和Avro。 
具體參考:http://tech.meituan.com/serialization_vs_deserialization.html 《序列化和反序列化》 <美團科技>

4. json介紹

爲什麼學習json? 
因爲 JSON 是 JavaScript 原生格式,這意味着使用json在web服務器和前端客戶端通信時,用 javascript 中處理 JSON 數據不需要任何特殊的 API 或工具包。 
json語法見http://www.json.org/json-zh.html

5. 使用json在web服務器和前端通信

例子見:http://blog.csdn.net/sunny_ss12/article/details/46643307

6. jsconcpp

C++要使用JSON來解析數據,一般採用jsoncpp。 
(1)Linux下編譯: 
https://github.com/open-source-parsers/jsoncpp 下載jsconcpp 
解壓,然後進入解壓根目錄 
參考https://github.com/open-source-parsers/jsoncpp對jsoncpp對jsoncpp進行編譯

 mkdir -p build/debug
 cd build/debug
 cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
 make 
 sudo make install

然後查看pkg-config/jsoncpp.pc.in,就可以看到jsoncpp的安裝目錄 
(2)使用doxygen編譯jsoncpp文檔

python doxybuild.py --doxygen=$(which doxygen) --open --with-dot
  • 1
  • 1

如果doxygen安裝在/usr/bin等環境變量path指定的目錄下, --doxygen=$(which doxygen)可以省掉 
--with-dot代表使用Graphviz的dot命令生成jsoncpp的函數調用圖。所以編譯文檔之前需要安裝Graphviz。centos運行sudo yum install graphviz即可。 
(3)使用方法: 
jsoncpp編譯爲靜態庫libjsoncpp.a,放到/usr/local/bin,頭文件在/usr/local/include/json/中 
編程程序後,直接使用-ljsoncpp來鏈接libjsoncpp即可。

7. jsoncpp示例代碼

示例代碼: 
http://www.cnblogs.com/kex1n/archive/2011/12/02/2272328.html 《jsoncpp的使用》 <小樓一夜聽春雨> 
http://blog.csdn.net/vagrxie/article/details/5754179 《數據/配置 的存儲方式 Json篇 以JsonCpp庫使用爲例》 <九天雁翎的博客> 
其中第一篇文章已轉載到自己的博客中。


轉載:http://blog.csdn.net/sunny_ss12/article/details/46684735

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章