第四部分: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);