C++高效解析JSON字符串

jopen 10年前發布 | 127K 次閱讀 JSON JSON開發包

1. 什么是JSON字符串說明?

定義:

JSON(Javascript Object Notation)是一種輕量級的數據交換格式,易于閱讀和編寫,也易于機器解析和生成。

結構:

a. 名稱/值 的集合,Json對象是鍵值對構成,類似于map。其鍵為普通字符串,值可以為任意類型,如數字、邏輯值、文本、數組對象、Json對象、null等。

b. 數組,Json對象也可以為一個數組,有一個或者多個數值構成,其中數值可以為任意類型,如數字、邏輯值、文本、數組對象、Json對象、null等。

c. 語法

數據在名稱/值對中

數據由逗號分隔

花括號保存對象

方括號保存數組

舉例:

a. 簡單例子:{"firstname": "peisheng"}

b. 多個數據:{"firstname": "peisheng", "lastname": "h", "email": "buzhidao"}

c. 數組例子:

{ "zubie": "cad",

"members": [

{"firstname": "peisheng", "lastname": "h", "email": "buzhidao"},

{"firstname": "peisheng", "lastname": "h", "email": "buzhidao"},

{"firstname": "peisheng", "lastname": "h", "email": "buzhidao"}

]

}

2. 為什么選擇Json作為數據傳輸?而不是XML

可讀性:JsonXML相比可謂不相上下,一邊是簡單的語法,一邊是規范的標簽形式,很難分出勝負。

可擴展性:XML天生有很好的可擴展性,Json也有。

編碼難度:XML有豐富的編碼工具,Json也有提供,但是XML要輸入很多結構字符。

解碼難度:凡是可擴展的數據結構,解析起來都很困難。

數據量: Json具有輕小的特點,降低了數據傳輸量。

3. JSONCPP庫介紹

目前市場上有很多Json解析的開源庫,http://www.json.org/,這個網站中有對Json的介紹,以及列出了各種語言實現的Json解析庫。JSONCPP是一個C++實現的面向對象的跨平臺開源庫,具有易用、易讀的特點。

JSONCPP中重要的類:

a. Json::Value 可以表示所有的類型,比如intstringobjectarray等。

b. Json::Reader 可以從Json字符串中解析出Json::Value對象。

c. Json::Writer 可以把Json::Value對象寫入到字符串流或者文件中。

但是JsonCPP解析性能低,使用了std標準庫的東西,在CAD的環境下很容易崩潰,最后放棄。

4. 如何讀取Json字符串?

解碼時,把Json字符串看成是一個map對象(object),對象(object)的鍵為字符串,值為任意類型,可以為intstringboolarrayobject等。解析Json字符串時,首先對當前層map解析解析,解析出key/val對。

解析過程:

a. 在鍵值對出現時,記錄鍵的起始位置,kvoff1_key, kvoff1_val

b. 在鍵值對結束時,記錄值的結束位置,kvoff2_key, kvoff2_val

c. 設置*kvoff2_key = 0, *kvoff2_val = 2

d. Json對象中,用map記錄鍵值的起始位置

e. 重復a~d四個步驟

舉例說明:

{"k1":"x1","k2":[1,2,3],"k3":{"k31":"v1"}}

按照上面的步驟進行解析

a. kvoff1_key=2, kvoff1_val=7

b. kvoff2_key=4, kv0ff2_val=9

c. *kvoff2_key=0, *kvoff2_val=0

d. Map.insert(kvoff1_key, kvoff1_val)

e. 重復a~d

5. 如何編輯Json字符串?

由于Json對象在內部維護了一份Json字符串內存RawBuf,插入時,在RawBuf后面添加一份鍵值對,并在所屬的Json對象中記錄一下鍵值對的起始位置,設置鍵和值的末尾值為0

如果追加的字符串的大小,比RawBuf剩余空間大時,添加List<TCHAR*> RawBufs字段,提供多緩沖支持,最后一個Buffer為當前正在使用的Buffer

RawBuf是使用步驟:

a. 初始化Json對象時,初始化一個 RAWBUFLEN=65535的TCHAR數組,并將該數組的指針添加到RawBufs中。

b. 插入一個鍵值對時,如果Buffer的剩余空間不足,生成一個大小為max(RAWBUFLEN, len(key) + len(val) + 2) 大小的TCHAR數組,并將數組的指針添加到RawBufs中,在將新值復制到剛才申請的空間里。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!