当前位置: 首页 > news >正文

RapidJSON 处理 JSON(高性能 C++ 库)(四)

第四部分: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,可以这样安装:

  1. 在 CMakeLists.txt中添加:

    include(FetchContent)
    FetchContent_Declare(
        rapidjson
        GIT_REPOSITORY https://github.com/Tencent/rapidjson.git
        GIT_TAG master
    )
    FetchContent_MakeAvailable(rapidjson)
    
  2. 然后在代码中 #include <rapidjson/document.h> 直接使用。

使用示例:

#include <iostream>
#include <rapidjson/document.h>

int main() {
   
    const char* json = R"({"name": "Alice", "age": 25, "skills": ["C++", "Python"]})";

    // 解析 JSON
    rapidjson::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;
}

代码说明:

  1. 创建 RapidJSON 文档对象:
    • rapidjson::Document document;:这是用来解析 JSON 数据的对象。它内部会保存 JSON 数据的结构。
  2. 解析 JSON 字符串:
    • document.Parse(json):解析给定的 JSON 字符串。如果解析成功,返回值为 true,否则会返回错误信息。
  3. 检查 JSON 成员并输出:
    • HasMember("name"):检查 JSON 对象是否包含名为 "name" 的字段。
    • document["name"].GetString():从 JSON 对象中提取 "name" 字段的值,并作为字符串输出。
  4. 输出解析结果:
    • 根据 JSON 中的字段,程序将输出每个字段的内容,例如 "name": "John" 将输出 Name: John

输出结果:

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 对象,传入 StringBuffer
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
    
    // 将 JSON 数据格式化并输出到 StringBuffer
    document.Accept(writer);

    

相关文章:

  • 检查是否存在占用内存过大的SQL
  • 服务器入门操作1(深度学习)
  • 【Deepseek、ChatGPT】智能气候前沿:AI Agent结合机器学习与深度学习在全球气候变化驱动因素预测中的应用
  • 高通Android10 铃声通话音频80%音量修改
  • 【Easylive】transferVideoFile 方法详细解析
  • 边缘计算的崛起:当计算从“云端漫步“变成“街头快闪“
  • ZLG嵌入式笔记 | 文件系统异步写入引发的问题
  • 魔改chromium——基础环境搭建
  • Go语言深度解析:从Java到Go的范式革命与实践指南
  • linux发布程序常用脚本
  • Skl-Videolingo-v2.0(VideoLingo):打破语言壁垒的下一代视频本地化工具
  • 云安全入门
  • spring-ai-alibaba第二章ollama集成EmbeddingModel
  • pyexcelerate在写入Excel时为何效率高?
  • Kotlin 协程官方文档知识汇总(二)
  • 详解隔离级别(4种),分别用表格展示问题出现的过程及解决办法
  • Geotools结合SLD实现矢量中文标注下的乱码和可用字体解析
  • 基于JavaWeb的二手图书交易系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 【云原生】Kubernetes CEL 速查表
  • 【Git “fetch“ 命令详解】
  • 游戏网站搭建需要多少钱/百度权重什么意思
  • 如何用word做网站/谷歌浏览器在线打开
  • 嘉兴专业网站建设/网站推广计划方案
  • 宠物网站建设论文/2023搜索最多的关键词
  • 门户网站建设投标书/网站后台管理系统
  • 淄博网站制作/电商最好卖的十大产品