首页 > 其他分享 >rapidjson使用总结

rapidjson使用总结

时间:2022-12-27 12:37:49浏览次数:59  
标签:总结 arraydoc json 使用 array include rapidjson allocator


目录​​(?)​​​​[-]​​

  1. ​​rapidjson简介​​
  2. ​​Dom解析示例​​

rapidjson简介

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

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

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

这里是官方教程:​​rapidjson官方教程​

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

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

Dom解析示例

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

// 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
// test.cpp
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include <fstream>
#include <string>
#include <cassert>
#include <iostream>
#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<StringBuffer> 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文件并保存


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. "inttag", 1, allocator);
21. "doubletag", 1.0, allocator);
22. "booltag", true, allocator);
23. "hellotag", "helloworld", allocator);
24.
25. // json 加入数组
26. array.PushBack(object, allocator);
27.
28. // json object 格式添加 “名称/值” 对
29. "json", "json string", allocator);
30. "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. "myhero.json");
38. FILE* file = fopen(path.c_str(), "wb");
39. if(file)
40. {
41. fputs(buffer.GetString(), file);
42. fclose(file);
43. }
44. "%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 格式单独编写解析方法,因此根据以上生成方法,解析方法应该为:


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. "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. char* titlech = FileUtils::getInstance()->getFileData(path, "r", &size);
23. 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. "GetParseError%s\n", readdoc.GetParseError());
30. }
31.
32. if(!readdoc.IsObject())
33. return 0;
34.
35. "json"];
36. const char* ch = _json.GetString();
37. cocos2d::log(ch);
38. cocos2d::log(_json.GetString());
39.
40. "array"];
41. if(_array.IsArray())
42. {
43. "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. "%d", _inttag);
52. }
53. if(arraydoc.HasMember("doubletag"))
54. {
55. double _doubletag = arraydoc["doubletag"].GetDouble();
56. "%lf", _doubletag);
57. }
58. if(arraydoc.HasMember("booltag"))
59. {
60. bool _booltag = arraydoc["booltag"].GetBool();
61. "%d", _booltag);
62. }
63. if(arraydoc.HasMember("hellotag"))
64. {
65. const char* _hellotag = arraydoc["hellotag"].GetString();
66. "%s", _hellotag);
67. }
68. }
69. }
70.
71. return 0;
72. }

CCLOG 的最终显示为:

json string
json string
test
1
1.000000
1
helloworld


rapidjson简介

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

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

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

这里是官方教程:​​rapidjson官方教程​

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

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

Dom解析示例

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



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

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

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

生成JSON文件并保存


 

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. "inttag", 1, allocator);
21. "doubletag", 1.0, allocator);
22. "booltag", true, allocator);
23. "hellotag", "helloworld", allocator);
24.
25. // json 加入数组
26. array.PushBack(object, allocator);
27.
28. // json object 格式添加 “名称/值” 对
29. "json", "json string", allocator);
30. "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. "myhero.json");
38. FILE* file = fopen(path.c_str(), "wb");
39. if(file)
40. {
41. fputs(buffer.GetString(), file);
42. fclose(file);
43. }
44. "%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 格式单独编写解析方法,因此根据以上生成方法,解析方法应该为:


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. "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. char* titlech = FileUtils::getInstance()->getFileData(path, "r", &size);
23. 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. "GetParseError%s\n", readdoc.GetParseError());
30. }
31.
32. if(!readdoc.IsObject())
33. return 0;
34.
35. "json"];
36. const char* ch = _json.GetString();
37. cocos2d::log(ch);
38. cocos2d::log(_json.GetString());
39.
40. "array"];
41. if(_array.IsArray())
42. {
43. "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. "%d", _inttag);
52. }
53. if(arraydoc.HasMember("doubletag"))
54. {
55. double _doubletag = arraydoc["doubletag"].GetDouble();
56. "%lf", _doubletag);
57. }
58. if(arraydoc.HasMember("booltag"))
59. {
60. bool _booltag = arraydoc["booltag"].GetBool();
61. "%d", _booltag);
62. }
63. if(arraydoc.HasMember("hellotag"))
64. {
65. const char* _hellotag = arraydoc["hellotag"].GetString();
66. "%s", _hellotag);
67. }
68. }
69. }
70.
71. return 0;
72. }

CCLOG 的最终显示为:

json string
json string
test
1
1.000000
1
helloworld

标签:总结,arraydoc,json,使用,array,include,rapidjson,allocator
From: https://blog.51cto.com/u_15923385/5971902

相关文章