第四部分:RapidJSON 處理 JSON(高性能 C++ 庫)
?? 快速掌握 JSON!文章 + 視頻雙管齊下 ??
如果你覺得閱讀文章太慢,或者更喜歡 邊看邊學 的方式,不妨直接觀看我錄制的 RapidJSON 課程視頻!?? 視頻里會用更直觀的方式講解 RapidJSON 的核心概念、實戰技巧,并配有動手演示,讓你更高效地掌握 RapidJSON 的處理方法!
當然,如果你喜歡深度閱讀,這篇文章會幫助你系統地理解 RapidJSON,從基礎到進階!無論你選擇哪種方式,最終目標都是讓你成為 RapidJSON 處理的高手!??
?? 點擊這里觀看視頻 ?? 視頻鏈接
一:RapidJSON 庫概述與環境配置
1.1 RapidJSON 是什么?
? RapidJSON 是一個高效、可移植的 C++ JSON 解析庫,專為高性能應用設計。它具有以下特點:
? 超快:比許多 JSON 庫(如 cJSON、JSONCPP)解析速度更快,適用于高性能應用。
? 全功能:支持DOM(文檔對象模型)解析和SAX(流式解析),適用于不同場景。
? 零依賴:僅使用 C++ 標準庫,無需額外的庫支持。
1.2 RapidJSON 適用場景
? 大規模數據處理(如日志分析、金融數據解析)。
? 游戲開發(解析游戲配置)。
? 嵌入式開發(存儲和解析 IoT 設備 JSON 數據)。
? 高并發服務器(解析 API 響應,提高吞吐量)。
1.3 下載和安裝 RapidJSON
方法 1:使用 vcpkg安裝(推薦)(Windows / Linux)
#如果使用 vcpkg 作為包管理工具,可以直接安裝:
vcpkg install rapidjson
方法 2:使用系統包管理器
- Ubuntu/Debian:
sudo apt install rapidjson-dev
- Mac(Homebrew):
brew install rapidjson
安裝后,在 CMakeLists.txt 中添加:
find_package(RapidJSON CONFIG REQUIRED)
然后在代碼中:
#include <rapidjson/document.h>
方法 2:手動下載
1.從 RapidJSON GitHub 下載源碼。
訪問該頁面,點擊綠色的 Code 按鈕,選擇 Download ZIP,然后解壓縮到你本地的某個目錄,或者使用 Git 命令進行克隆:
git clone https://github.com/Tencent/rapidjson.git
2.將 include目錄加入項目:
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h" // 用于格式化輸出
#include "rapidjson/stringbuffer.h" // 用于緩存輸出
這些頭文件提供了 RapidJSON 主要功能的接口:
-
document.h
:用于解析 JSON 數據并創建 JSON 對象。 -
prettywriter.h
:用于將 JSON 數據格式化為易讀的字符串。 -
stringbuffer.h
:用于將 JSON 數據寫入字符串。
3.RapidJSON 僅包含頭文件,因此無需編譯。
? RapidJSON 是只有頭文件的 C++ 庫。只需把 include/rapidjson
目錄復制至系統或項目的 include 目錄中。
1.4 在 C++ 項目中集成 RapidJSON(CMake / vcpkg)
如果項目使用 CMake
,可以這樣安裝:
-
在 CMakeLists.txt中添加:
include(FetchContent) FetchContent_Declare(rapidjsonGIT_REPOSITORY https://github.com/Tencent/rapidjson.gitGIT_TAG master ) FetchContent_MakeAvailable(rapidjson)
-
然后在代碼中
#include <rapidjson/document.h>
直接使用。
使用示例:
#include <iostream>
#include <rapidjson/document.h>int main() {const char* json = R"({"name": "Alice", "age": 25, "skills": ["C++", "Python"]})";// 解析 JSONrapidjson::Document doc;doc.Parse(json);// 讀取數據if (doc.HasMember("name") && doc["name"].IsString()) {std::cout << "Name: " << doc["name"].GetString() << std::endl;}if (doc.HasMember("age") && doc["age"].IsInt()) {std::cout << "Age: " << doc["age"].GetInt() << std::endl;}if (doc.HasMember("skills") && doc["skills"].IsArray()) {std::cout << "Skills: ";for (auto& skill : doc["skills"].GetArray()) {std::cout << skill.GetString() << " ";}std::cout << std::endl;}return 0;
}
二:使用 RapidJSON 解析 JSON
- 解析 JSON 字符串為 RapidJSON DOM
- 訪問 JSON 對象的鍵值對和數組元素
- 使用 SAX 解析大 JSON 文件(事件驅動方式)
2.1 解析 JSON 對象
2.1.1 解析基本 JSON
? 目標 JSON
{"name": "張三","age": 30,"married": true
}
? C++ 代碼
#include <iostream>
#include "rapidjson/document.h"int main() {const char* json = R"({"name": "張三", "age": 30, "married": true})";rapidjson::Document doc;if (doc.Parse(json).HasParseError()) {cout << "JSON 解析失敗!" << endl;return -1;}std::cout << "姓名: " << doc["name"].GetString() << endl;cout << "年齡: " << doc["age"].GetInt() << endl;cout << "已婚: " << (doc["married"].GetBool() ? "是" : "否") << endl;return 0;
}
? 輸出
姓名: 張三
年齡: 30
已婚: 是
2.1.2 解析 JSON 數據并輸出
#include <iostream>
#include "rapidjson/document.h"int main() {// JSON 字符串const char* json = R"({"name": "John","age": 30,"city": "New York"})";// 創建 RapidJSON 文檔對象rapidjson::Document document;// 解析 JSON 字符串if (document.Parse(json).HasParseError()) {std::cerr << "JSON 解析失敗!" << std::endl;return 1;}// 檢查并輸出每個成員if (document.HasMember("name") && document["name"].IsString()) {std::cout << "Name: " << document["name"].GetString() << std::endl;}if (document.HasMember("age") && document["age"].IsInt()) {std::cout << "Age: " << document["age"].GetInt() << std::endl;}if (document.HasMember("city") && document["city"].IsString()) {std::cout << "City: " << document["city"].GetString() << std::endl;}return 0;
}
代碼說明:
- 創建 RapidJSON 文檔對象:
rapidjson::Document document;
:這是用來解析 JSON 數據的對象。它內部會保存 JSON 數據的結構。
- 解析 JSON 字符串:
document.Parse(json)
:解析給定的 JSON 字符串。如果解析成功,返回值為true
,否則會返回錯誤信息。
- 檢查 JSON 成員并輸出:
HasMember("name")
:檢查 JSON 對象是否包含名為"name"
的字段。document["name"].GetString()
:從 JSON 對象中提取"name"
字段的值,并作為字符串輸出。
- 輸出解析結果:
- 根據 JSON 中的字段,程序將輸出每個字段的內容,例如
"name": "John"
將輸出Name: John
。
- 根據 JSON 中的字段,程序將輸出每個字段的內容,例如
輸出結果:
Name: John
Age: 30
City: New York
2.1.3 進一步擴展
你可以擴展這個示例,處理更多復雜的 JSON 數據,甚至解析嵌套的 JSON 對象或數組。
解析嵌套 JSON 對象
假設我們有一個更復雜的 JSON 字符串,包含嵌套的 JSON 對象:
{"name": "John","age": 30,"address": {"street": "5th Avenue","city": "New York"}
}
你可以如下解析:
#include <iostream>
#include "rapidjson/document.h"int main() {const char* json = R"({"name": "John","age": 30,"address": {"street": "5th Avenue","city": "New York"}})";rapidjson::Document document;if (document.Parse(json).HasParseError()) {std::cerr << "JSON 解析失敗!" << std::endl;return 1;}// 輸出基礎字段std::cout << "Name: " << document["name"].GetString() << std::endl;std::cout << "Age: " << document["age"].GetInt() << std::endl;// 解析嵌套的 JSON 對象 "address"if (document.HasMember("address") && document["address"].IsObject()) {const rapidjson::Value& address = document["address"];std::cout << "Street: " << address["street"].GetString() << std::endl;std::cout << "City: " << address["city"].GetString() << std::endl;}return 0;
}
輸出結果:
Name: John
Age: 30
Street: 5th Avenue
City: New York
總結:
- 使用 RapidJSON 可以方便地解析 JSON 字符串,提取其中的數據,并進行相應的處理。
- 解析時需要檢查字段是否存在,避免訪問不存在的字段引發錯誤。
- 可以解析簡單的 JSON 字符串,也可以處理嵌套的 JSON 對象,甚至是數組等復雜數據結構。
2.2 解析 JSON 數組
?? 示例 2:解析數組
? 目標 JSON
{"cities": ["北京", "上海", "廣州"]
}
? C++ 代碼
const char* json = R"({"cities": ["北京", "上海", "廣州"]})";
Document doc;
doc.Parse(json);const Value& cities = doc["cities"];
for (SizeType i = 0; i < cities.Size(); i++) {cout << "城市 " << i + 1 << ": " << cities[i].GetString() << endl;
}
? 輸出
城市 1: 北京
城市 2: 上海
城市 3: 廣州
2.3 解析并格式化輸出 JSON 數據
RapidJSON 提供了 PrettyWriter
類,允許你對 JSON 數據進行格式化輸出,加入縮進、換行等
代碼示例:解析并格式化輸出 JSON 數據
#include <iostream>
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"int main() {// 原始 JSON 字符串const char* json = R"({"name": "John","age": 30,"city": "New York"})";// 創建 RapidJSON 文檔對象rapidjson::Document document;// 解析 JSON 字符串if (document.Parse(json).HasParseError()) {std::cerr << "JSON 解析失敗!" << std::endl;return 1;}// 創建一個 StringBuffer 用于保存格式化后的 JSON 字符串rapidjson::StringBuffer buffer;// 創建 PrettyWriter 對象,傳入 StringBufferrapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);// 將 JSON 數據格式化并輸出到 StringBufferdocument.Accept(writer);