RapidJSON 是腾讯的开源 json 解析框架,RapidJSON 的 github 地址。
RapidJSON 有很多优点,以下是 RapidJSON 文档中的介绍:
RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。
RapidJSON 快。它的性能可与 strlen() 相比。可支持 SSE2/SSE4.2 加速。
RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。
RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及 “\u0000”(空字符)。
在这里简单的介绍下 RapidJSON 的安装以及简单的使用方法。
RapidJSON 是只有头文件的 C++ 库,安装方法非常简单,只需要将 RapidJSON 的 include/rapidjson 文件夹放到系统或者项目的 include 目录中,然后 #include <需要的文件名> 即可。
RapidJSON 有非常详细的文档,在这里我们介绍下简单的读取、写入 .json 文件,以及对数据的读取与修改。
int main()
{
//读
FILE *fp = fopen("pass1.json", "rb");//非Windows系统使用"r"
char readBuffer[65536];
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
Document d;
d.ParseStream(is);
fclose(fp);
//写
FILE *outf = fopen("output.json", "wb");非Windows系统使用"w"
char writeBuffer[65536];
FileWriteStream os(outf, writeBuffer, sizeof(writeBuffer));
PrettyWriter writer(os);
d.Accept(writer);
fclose(outf);
return 0;
}
以上代码读取 pass1.json 文件到一个 Document 中,而后将 Document 数据写入 output.json 中。
在写入的过程中,我们使用了 PrettyWriter 而不是 Writer, 区别是使用 Writer 会将数据都写到一行中,不方便人眼观察数据,而 PrettyWriter 会自动换行,将格式变为我们通常所见到的那样,方便观察数据。
上面我们看到,RapidJSON 可以将 .json 文件数据解析到 Document 中,而后我们可以读取或修改 Document 来获取或者修改 json 数据。
我们用 C 语言的字符串储存一个 JSON, 把它解析至一个 Document:
const char* json = "{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1, 2, 3, 4]}";
Document d;
d.Parse(json);
此时 这个 Document 的结构如下图所示:
然后我们读取”hello” 的 Value:
if (!d.IsObject())
{
cout << "error1" << endl;
}
if (!d.HasMember("hello"))
{
cout << "error2" << endl;
}
if (!d["hello"].IsString())
{
cout << "error3" << endl;
}
cout << d["hello"].GetString() << endl;
在官方文档中,使用的是assert()
但是我在实际使用中不知道为什么总是异常中断,不过好在IsObject()
这些函数本身返回的是 bool 值,我们也可以自己判断。
然后是对 Document 添加成员,删除成员,修改值的一些操作:
Value v1;
v1.SetInt(666);
Value v2(3.14);//调用Value(double)
Document::AllocatorType &allocator = d.GetAllocator();
d.AddMember("v1", v1, allocator);
d.AddMember("v2", v2, allocator);
d.RemoveMember("hello");
d["i"].SetInt(456);
在上面代码中,我们创建了两个 Value v1 与 v2 并且将其添加到 d 这个 Document 中,然后删除了 d 中名为 “hello” 的成员,并且将 “i” 的值修改为 456。
最后,我们将 d 转为 json 风格的字符串打印出来看看结果:
StringBuffer buffer;
PrettyWriter writer(buffer);
d.Accept(writer);
cout << buffer.GetString() << endl;