rapidjson使用总结
发布日期:2021-06-30 15:59:54 浏览次数:2 分类:技术文章

本文共 6120 字,大约阅读时间需要 20 分钟。

目录

rapidjson简介

rapidjson是腾讯的开源json解析框架,用c++实现。由于全部代码仅用header file实现,所以很容易集成到项目中。

rapidjson的性能是很出色的,其作者做了28个C/C++ JSON库的评测,里有的结果截图。

rapidjson的另一个特点是对json的标准符合程度是100%的(在开启了full precision选项的情况下)。

这里是官方教程:

这里是原作者对rapidjson代码的剖析:

我之前的项目使用的是jsoncpp,最近在把解析json的代码交叉编译到设备的时候,偶尔会出现crash的情况。虽然经过检查是代码写的有问题,不是jsoncpp的问题,在解决问题过程中尝试了rapidjson这个库,并顺便对比了一下jsoncpp和rapidjson对我项目中json文件的解析速度。

Dom解析示例

下面是我写的一个小例子,从test.json文件中读取内容并解析。其他代码示例也可以查看我的github仓库中关于rapidjson的测试代码:.

 
// test.json
{
   "dictVersion": 1,  
   "content":  
   [  
       {
"key": "word1", "value": "单词1"} ,
       {
"key": "word2", "value": "单词2"} ,
       {
"key": "word3", "value": "单词3"} ,
       {
"key": "word4", "value": "单词4"} ,
       {
"key": "word5", "value": "单词5"}
   ]
}
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
 
// test.cpp
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include 
#include 
#include 
#include 
#define psln(x) std::cout << #x " = " << (x) << std::endl
void testSimpleDoc() {
   using std::string;
   using std::ifstream;
   // read json content into string.
   string      stringFromStream;
   ifstream    in;
   in.open("test.json", ifstream::in);
   if (!in.is_open())
       return;
   string line;
   while (getline(in, line)) {
       stringFromStream.append(line + "\n");
   }
   in.close();
   // ---------------------------- read json --------------------
   // parse json from string.
   using rapidjson::Document;
   Document doc;
   doc.Parse<0>(stringFromStream.c_str());
   if (doc.HasParseError()) {
       rapidjson::ParseErrorCode code = doc.GetParseError();
       psln(code);
       return;
   }
   // use values in parse result.
   using rapidjson::Value;
   Value & v = doc["dictVersion"];
   if (v.IsInt()) {
       psln(v.GetInt());
   }
   Value & contents = doc["content"];
   if (contents.IsArray()) {
       for (size_t i = 0; i < contents.Size(); ++i) {
           Value & v = contents[i];
           assert(v.IsObject());
           if (v.HasMember("key") && v["key"].IsString()) {
               psln(v["key"].GetString());
           }
           if (v.HasMember("value") && v["value"].IsString()) {
               psln(v["value"].GetString());
           }
       }
   }
   // ---------------------------- write json --------------------
   pcln("add a value into array");
   Value item(Type::kObjectType);
   item.AddMember("key", "word5", doc.GetAllocator());
   item.AddMember("value", "单词5", doc.GetAllocator());
   contents.PushBack(item, doc.GetAllocator());
   // convert dom to string.
   StringBuffer buffer;      // in rapidjson/stringbuffer.h
   Writer
writer(buffer); // in rapidjson/writer.h
   doc.Accept(writer);
   psln(buffer.GetString());
}

Cocos2d-x 3.0 加入了rapidjson库用于json解析。位于项目的cocos2d/external/json下。

rapidjson 是一个不需要包含 .lib 和 .dll 即可运行的可见代码库。项目 wiki 见。下面通过两个实例来深入了解它在 cocos2dx 中的用法。

注:CCLOG() 函数需要在 DEBUG 模式下才有作用。

生成JSON文件并保存

[cpp]   
 
 
  1. #include "CCStdC.h"  
  2. #include "cocos2d.h"  
  3. #include "json/document.h"  
  4. #include "json/writer.h"  
  5. #include "json/stringbuffer.h"  
  6. using namespace  rapidjson;  
  7.   
  8. USING_NS_CC;  
  9.   
  10. int main()  
  11. {  
  12.     //*** 生成 json 文件,存储在 getWritablePath 文件夹下 ***  
  13.     rapidjson::Document writedoc;  
  14.     writedoc.SetObject();  
  15.     rapidjson::Document::AllocatorType& allocator = writedoc.GetAllocator();  
  16.     rapidjson::Value array(rapidjson::kArrayType);  
  17.     rapidjson::Value object(rapidjson::kObjectType);  
  18.       
  19.     // json object 格式添加 “名称/值” 对  
  20.     object.AddMember("inttag", 1, allocator);  
  21.     object.AddMember("doubletag", 1.0, allocator);  
  22.     object.AddMember("booltag"true, allocator);  
  23.     object.AddMember("hellotag""helloworld", allocator);  
  24.       
  25.     // json 加入数组  
  26.     array.PushBack(object, allocator);  
  27.       
  28.     // json object 格式添加 “名称/值” 对  
  29.     writedoc.AddMember("json""json string", allocator);  
  30.     writedoc.AddMember("array", array, allocator);  
  31.    
  32.     StringBuffer buffer;  
  33.     rapidjson::Writer<StringBuffer> writer(buffer);  
  34.     writedoc.Accept(writer);  
  35.   
  36.     auto path = FileUtils::getInstance()->getWritablePath();  
  37.     path.append("myhero.json");  
  38.     FILE* file = fopen(path.c_str(), "wb");  
  39.     if(file)  
  40.     {  
  41.         fputs(buffer.GetString(), file);  
  42.         fclose(file);  
  43.     }  
  44.     CCLOG("%s",buffer.GetString());  
  45.   
  46.     return 0;  
  47. }  

我是用 VS2012 编译的,最终生成的json文件位于 \proj.win32\Debug.win32 文件夹下。打开内容如下:

{"json":"json string","array":[{"inttag":1,"doubletag":1,"booltag":true,"hellotag":"helloworld"}]}

读取JSON文件并显示

rapidjson 需要根据原 json 格式单独编写解析方法,因此根据以上生成方法,解析方法应该为:

[cpp]   
 
 
  1. #include "CCStdC.h"  
  2. #include "cocos2d.h"  
  3. #include "json/document.h"  
  4. #include "json/writer.h"  
  5. #include "json/stringbuffer.h"  
  6. using namespace  rapidjson;  
  7.   
  8. USING_NS_CC;  
  9.   
  10. int main()  
  11. {  
  12.     auto path = FileUtils::getInstance()->getWritablePath();  
  13.     path.append("myhero.json");  
  14.   
  15.     //*** 读取 json 文件 ***  
  16.     rapidjson::Document readdoc;  
  17.     bool bRet = false;  
  18.     ssize_t size = 0;  
  19.     std::string load_str;  
  20.   
  21.     // getFileData 如果不指定,读取根目录是 Resource 文件夹  
  22.     unsigned char* titlech = FileUtils::getInstance()->getFileData(path, "r", &size);  
  23.     load_str = std::string((const char*)titlech,size);  
  24.   
  25.     //load_str = cocos2d::FileUtils::getInstance()->getStringFromFile("..\\myhero.json");  
  26.     readdoc.Parse<0>(load_str.c_str());     
  27.     if(readdoc.HasParseError())  
  28.     {  
  29.         CCLOG("GetParseError%s\n", readdoc.GetParseError());  
  30.     }  
  31.   
  32.     if(!readdoc.IsObject())  
  33.         return 0;  
  34.   
  35.     rapidjson::Value& _json = readdoc["json"];  
  36.     const char* ch = _json.GetString();  
  37.     cocos2d::log(ch);  
  38.     cocos2d::log(_json.GetString());  
  39.   
  40.     rapidjson::Value& _array = readdoc["array"];  
  41.     if(_array.IsArray())  
  42.     {  
  43.         CCLOG("test");  
  44.         for(int i=0; i<_array.Capacity(); i++)  
  45.         {  
  46.             //CCLOG("%d", i);  
  47.             rapidjson::Value& arraydoc = _array[i];  
  48.             if(arraydoc.HasMember("inttag"))  
  49.             {  
  50.                 int _inttag = arraydoc["inttag"].GetInt();  
  51.                 CCLOG("%d", _inttag);  
  52.             }  
  53.             if(arraydoc.HasMember("doubletag"))  
  54.             {  
  55.                 double _doubletag = arraydoc["doubletag"].GetDouble();  
  56.                 CCLOG("%lf", _doubletag);  
  57.             }  
  58.             if(arraydoc.HasMember("booltag"))  
  59.             {  
  60.                 bool _booltag = arraydoc["booltag"].GetBool();  
  61.                 CCLOG("%d", _booltag);  
  62.             }  
  63.             if(arraydoc.HasMember("hellotag"))  
  64.             {  
  65.                 const char* _hellotag = arraydoc["hellotag"].GetString();  
  66.                 CCLOG("%s", _hellotag);  
  67.             }  
  68.         }  
  69.     }  
  70.   
  71.     return 0;  
  72. }  
CCLOG 的最终显示为:

json string

json string
test
1
1.000000
1
helloworld

转载地址:https://kaitiren.blog.csdn.net/article/details/78106463 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:cocos2dx-lua在ios上实现生成及扫描二维码
下一篇:cocos2dx luabinding C/C++/LUA部分

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月10日 07时11分20秒