本文由 AI 辅助生成,内容已验证可用

概述

RapidJSON 是一个 C++ 的 JSON 解析器及生成器,灵感来自 RapidXml。

核心特点:

  • 高性能:使用 SIMD 指令加速解析
  • 头文件库:无需编译,直接包含即可使用
  • 内存友好:支持原位解析,减少内存分配
  • 标准兼容:支持 JSON 标准 RFC7159 和 ECMA-404
  • 跨平台:支持各大编译器和操作系统

官方文档:RapidJSON 主页


快速开始

安装

RapidJSON 是纯头文件库,只需下载并包含头文件即可:

# 方式一:直接下载
git clone https://github.com/Tencent/rapidjson.git
 
# 方式二:使用 vcpkg
vcpkg install rapidjson
 
# 方式三:使用 CMake FetchContent
include(FetchContent)
FetchContent_Declare(
    rapidjson
    GIT_REPOSITORY https://github.com/Tencent/rapidjson.git
    GIT_TAG master
)
FetchContent_MakeAvailable(rapidjson)

包含头文件

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include <iostream>
 
using namespace rapidjson;

核心 API

1. 解析 JSON 字符串

// 从字符串解析
const char* json = R"({
    "name": "小明",
    "age": 25,
    "skills": ["C++", "Python", "Rust"],
    "active": true
})";
 
Document doc;
doc.Parse(json);
 
// 检查解析错误
if (doc.HasParseError()) {
    std::cerr << "解析错误: " << doc.GetParseError() << std::endl;
    return -1;
}

2. 访问 JSON 值

// 获取对象成员
assert(doc.HasMember("name"));
assert(doc["name"].IsString());
std::string name = doc["name"].GetString();
 
// 获取数值
int age = doc["age"].GetInt();
bool active = doc["active"].GetBool();
 
// 获取数组
const Value& skills = doc["skills"];
assert(skills.IsArray());
for (SizeType i = 0; i < skills.Size(); i++) {
    std::cout << "Skill: " << skills[i].GetString() << std::endl;
}
 
// 使用迭代器遍历
for (Value::ConstMemberIterator itr = doc.MemberBegin();
     itr != doc.MemberEnd(); ++itr) {
    std::cout << itr->name.GetString() << ": ";
    // 根据 value 类型输出
}

3. 创建 JSON 文档

Document doc;
doc.SetObject();
 
// 添加字符串
Document::AllocatorType& allocator = doc.GetAllocator();
doc.AddMember("name", "小明", allocator);
 
// 添加数值
doc.AddMember("age", 25, allocator);
 
// 添加布尔值
doc.AddMember("active", true, allocator);
 
// 创建数组
Value skills(kArrayType);
skills.PushBack("C++", allocator);
skills.PushBack("Python", allocator);
doc.AddMember("skills", skills, allocator);
 
// 创建嵌套对象
Value address(kObjectType);
address.AddMember("city", "北京", allocator);
address.AddMember("zip", "100000", allocator);
doc.AddMember("address", address, allocator);

4. 序列化输出

// 方式一:紧凑格式
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
std::cout << buffer.GetString() << std::endl;
 
// 方式二:美化格式(带缩进)
StringBuffer buffer;
PrettyWriter<StringBuffer> prettyWriter(buffer);
doc.Accept(prettyWriter);
std::cout << buffer.GetString() << std::endl;

进阶用法

原位解析(In-situ Parsing)

减少内存分配,直接修改原始 JSON 字符串:

char json[] = R"({"name":"小明","age":25})";
Document doc;
doc.ParseInsitu(json);  // 直接在原字符串上解析
 
// 注意:原字符串会被修改

自定义内存分配器

// 使用内存池分配器,提升性能
MemoryPoolAllocator<> allocator;
Document doc(&allocator);

处理大文件(流式解析)

#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
 
// 读取大文件
FILE* fp = fopen("large.json", "rb");
char readBuffer[65536];
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
 
Document doc;
doc.ParseStream(is);
fclose(fp);
 
// 写入大文件
FILE* fp2 = fopen("output.json", "wb");
char writeBuffer[65536];
FileWriteStream os(fp2, writeBuffer, sizeof(writeBuffer));
PrettyWriter<FileWriteStream> writer(os);
doc.Accept(writer);
fclose(fp2);

JSON Schema 验证

#include "rapidjson/schema.h"
 
Document sd;
sd.Parse(R"({
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer", "minimum": 0}
    },
    "required": ["name", "age"]
})");
 
SchemaDocument schema(sd);
Document doc;
doc.Parse(R"({"name":"小明","age":25})");
 
SchemaValidator validator(schema);
if (!doc.Accept(validator)) {
    // 验证失败,输出错误信息
    StringBuffer sb;
    validator.GetInvalidSchemaPointer().StringifyUriFragment(sb);
    printf("Invalid schema: %s\n", sb.GetString());
    printf("Invalid keyword: %s\n", validator.GetInvalidSchemaKeyword());
}

类型判断与转换

类型判断 API

Value v;
v.IsNull();      // 是否为 null
v.IsFalse();     // 是否为 false
v.IsTrue();      // 是否为 true
v.IsBool();      // 是否为布尔值
v.IsObject();    // 是否为对象
v.IsArray();     // 是否为数组
v.IsString();    // 是否为字符串
v.IsNumber();    // 是否为数值
v.IsInt();       // 是否为 int
v.IsUint();      // 是否为 unsigned int
v.IsInt64();     // 是否为 int64_t
v.IsUint64();    // 是否为 uint64_t
v.IsDouble();    // 是否为 double

数值获取 API

v.GetInt();      // 获取 int
v.GetUint();     // 获取 unsigned int
v.GetInt64();    // 获取 int64_t
v.GetUint64();   // 获取 uint64_t
v.GetDouble();   // 获取 double
v.GetBool();     // 获取 bool
v.GetString();   // 获取 const char*
v.GetStringLength(); // 获取字符串长度

常见问题

1. 中文乱码问题

RapidJSON 原生支持 UTF-8,确保源文件编码为 UTF-8:

// 使用 UTF-8 编码保存文件
const char* json = R"({"name":"小明"})";

2. 内存泄漏问题

使用内存池分配器时,注意生命周期:

void ProcessJson() {
    MemoryPoolAllocator<> allocator;
    Document doc(&allocator);
    // ... 使用 doc
    // 离开作用域,自动释放
}

3. 性能优化建议

  • 使用 ParseInsitu() 减少内存分配
  • 重用 Document 和 Allocator 对象
  • 对于大量小 JSON,使用内存池分配器
  • 启用 SIMD 优化(需要编译器支持)

完整示例

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/prettywriter.h"
#include <iostream>
 
using namespace rapidjson;
 
int main() {
    // 1. 创建 JSON 文档
    Document doc;
    doc.SetObject();
    Document::AllocatorType& allocator = doc.GetAllocator();
 
    // 2. 添加数据
    doc.AddMember("project", "RapidJSON Demo", allocator);
    doc.AddMember("version", 1.0, allocator);
    
    Value tags(kArrayType);
    tags.PushBack("JSON", allocator);
    tags.PushBack("C++", allocator);
    tags.PushBack("高性能", allocator);
    doc.AddMember("tags", tags, allocator);
 
    // 3. 序列化输出
    StringBuffer buffer;
    PrettyWriter<StringBuffer> writer(buffer);
    doc.Accept(writer);
    
    std::cout << "生成的 JSON:\n" << buffer.GetString() << std::endl;
 
    // 4. 解析 JSON
    Document parsedDoc;
    parsedDoc.Parse(buffer.GetString());
 
    // 5. 访问数据
    std::cout << "\n解析结果:\n";
    std::cout << "Project: " << parsedDoc["project"].GetString() << std::endl;
    std::cout << "Version: " << parsedDoc["version"].GetDouble() << std::endl;
 
    return 0;
}

输出结果:

{
    "project": "RapidJSON Demo",
    "version": 1.0,
    "tags": ["JSON", "C++", "高性能"]
}
 
解析结果:
Project: RapidJSON Demo
Version: 1.0

相关链接


总结

RapidJSON 是一个高性能、易用、功能完善的 C++ JSON 库,适合:

✅ 需要高性能 JSON 解析的项目
✅ 嵌入式或内存受限环境
✅ 只需头文件即可集成的场景
✅ 需要流式解析大文件的场景

如果你的项目需要处理 JSON,RapidJSON 是一个非常值得考虑的选择。