使用rapidjson附加到文件上的现有JSON对象数组

时间:2016-08-23 20:38:52

标签: rapidjson

我有一个类似于下面的JSON对象数组:

[
    {"hello": "rapidjson",
    "t": true,
    "f": false,
    "n": null,
    "i": 2,
    "pi": 3.1416},
   {"hello": "rapidjson",
    "t": true,
    "f": false,
    "n": null,
    "i": 12,
    "pi": 3.88},
    {"hello": "rapidjson",
    "t": true,
    "f": false,
    "n": null,
    "i": 14,
    "pi": 3.99}
]

我的应用程序吐出了一堆JSON对象,我需要每30秒将其添加到一个JSON文件中。

每一轮我需要附加到同一个文件并将新的JSON对象添加到我拥有的JSON对象数组中。每个JSON文件的第一个条目是JSON模式。

我面临的问题是我不知道每次如何读取上一个文件并将新对象添加到文件中现有对象的数组中并写回更新的文件。

请您提供指导,告诉我需要做什么?或者指出几个例子(无法在教程中找到类似的例子)?

2 个答案:

答案 0 :(得分:0)

假设文件中当前的JSON对象数组是:

[{“one”,“1”},{“two”,“2”}]

我们要添加一个JSON对象 - > {“three”,“3”}并将其写回同一文件,以便最终文件如下所示:[{“one”,“1”},{“two”,“2”},{“three “,”3“}}

以下是完整步骤的列表:

using namespace rapidjson;

 FILE* fp = fopen(json_file_name.c_str(), "r");
 char readBuffer[65536];
 FileReadStream is(fp, readBuffer, sizeof(readBuffer));

 Document d, d2;
 d.ParseStream(is);
 assert(d.IsArray());
 fclose(fp);
 d2.SetObject();
 Value json_objects(kObjectType);
 json_objects.AddMember("three", "3", d2.GetAllocator());
 d.PushBack(json_objects, d2.GetAllocator());

 FILE* outfile = fopen(json_file_name.c_str(), "w");
 char writeBuffer[65536];
 FileWriteStream os(outfile, writeBuffer, sizeof(writeBuffer));

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

答案 1 :(得分:0)

这篇文章来自几年前,但我的回答仍然有意义。我和@SamZ有同样的问题。这个答案从多个方面改进了@SamZ的答案:

  1. 不需要读取或解析现有文件
  2. 将新对象直接添加到现有文件中,而无需合并文档

代码如下:

bool appendToFile(const std::string& filename, const rapidjson::Document& document)
{
    using namespace rapidjson;
    
    // create file if it doesn't exist
    if (FILE* fp = fopen(filename.c_str(), "r"); !fp)
    {
        if (fp = fopen(filename.c_str(), "w"); !fp)
            return false;
        fputs("[]", fp);
        fclose(fp);
    }

    // add the document to the file
    if (FILE* fp = fopen(filename.c_str(), "rb+"); fp)
    {
        // check if first is [
        std::fseek(fp, 0, SEEK_SET);
        if (getc(fp) != '[')
        {
            std::fclose(fp);
            return false;
        }

        // is array empty?
        bool isEmpty = false;
        if (getc(fp) == ']')
            isEmpty = true;

        // check if last is ]
        std::fseek(fp, -1, SEEK_END);
        if (getc(fp) != ']')
        {
                std::fclose(fp);
                return false;
        }

        // replace ] by ,
        fseek(fp, -1, SEEK_END);
        if (!isEmpty)
            fputc(',', fp);

        // append the document
        char writeBuffer[65536];
        FileWriteStream os(fp, writeBuffer, sizeof(writeBuffer));
        Writer<FileWriteStream> writer(os);
        document.Accept(writer);

        // close the array
        std::fputc(']', fp);
        fclose(fp);
        return true;
    }
    return false;
}