rapidjson: dump/load json data to/from file

这里不讨论为什么要用 json,仅仅记录如何把内存中的结构体存储为 json 格式的文件,以及如何把 json 格式的文件内容读入内存;

从内存中的字符串得到 json 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 假设我们用 C 语言的字符串储存一个 JSON(const char* json):
{
"hello": "world",
"t": true ,
"f": false,
"n": null,
"i": 123,
"pi": 3.1416,
"a": [1, 2, 3, 4]
}
*/
// 把它解析至一个 Document:
#include "rapidjson/document.h"

using namespace rapidjson;

// ...
Document document;
document.Parse(json);

通过自定义从 0 构造一个 json 对象

1
2
3
4
5
6
7
8
9
10
#include "rapidjson/document.h"

using namespace rapidjson;

// ...
Document d;
Document::AllocatorType& allocator = d.GetAllocator();
// Create the block object at root of DOM
d.SetObject();
d.AddMember("ID", 8086, allocator);

从文件解析一个 json

  • 如果文件很小,可以全部读入内存,那么可以使用内存流把 json 存储在内存中,然后去解析
  • 如果文件很大,不能一次性全部读入内存,那么可以使用文件流,每次读入一部分去做解析

内存流输入:

StringStream

1
2
3
4
5
6
7
8
9
10
#include "rapidjson/document.h" // 会包含 "rapidjson/rapidjson.h"

using namespace rapidjson;

// ...
const char json[] = "[1, 2, 3, 4]"; // json 可以看作是从文件中读入的内容
StringStream s(json);

Document d;
d.ParseStream(s);

内存流输出:

StringBuffer

StringBuffer 是一个简单的输出流。它分配一个内存缓冲区,供写入整个 json。可使用 GetString() 来获取该缓冲区。

1
2
3
4
5
6
7
8
#include "rapidjson/stringbuffer.h"
#include <rapidjson/writer.h>

StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
d.Accept(writer);

const char* output = buffer.GetString();
  • Writer<StringBuffer> writer(buffer); 表示:告诉 writer 把最终 json 字符串写到 buffer 中去;
  • d.Accept(writer); 表示:Document 把要写的内容告诉 writer;
  • 可使用 GetString() 来获取该缓冲区。

文件流输入:

FileReadStream

FileReadStream 通过 FILE 指针读取文件。使用者需要提供一个缓冲区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "rapidjson/filereadstream.h"
#include <cstdio>

using namespace rapidjson;

FILE* fp = fopen("big.json", "rb"); // 非 Windows 平台使用 "r"

char readBuffer[65536];
FileReadStream is(fp, readBuffer, sizeof(readBuffer)); // 通过 readBuffer 从文件 fp 中读取 sizeof(readBuffer) 个字节到 is 中

Document d;
d.ParseStream(is);

fclose(fp);

文件流输出:

FileWriteStream

FileWriteStream 是一个含缓冲功能的输出流。它的用法与 FileReadStream 非常相似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "rapidjson/filewritestream.h"
#include <rapidjson/writer.h>
#include <cstdio>

using namespace rapidjson;

Document d;
d.Parse(json);
// ...

FILE* fp = fopen("output.json", "wb"); // 非 Windows 平台使用 "w"

char writeBuffer[65536];
FileWriteStream os(fp, writeBuffer, sizeof(writeBuffer));

Writer<FileWriteStream> writer(os);
d.Accept(writer);

fclose(fp);

可以看到输入流都是,Document::ParseStream(istream),输出流都是 Document::Accept(Document::Writer)

参考