rapidjson简介
rapidjson是腾讯的开源json解析框架,用c++实现。由于全部代码仅用header file实现,所以很容易集成到项目中。
rapidjson的性能是很出色的,其作者Milo Yipz做了28个C/C++ JSON库的评测,这个链接里有测试的结果截图https://www.zhihu.com/question/23654513。
rapidjson的另一个特点是对json的标准符合程度是100%的(在开启了full precision选项的情况下)。
这里是官方教程:http://rapidjson.org/zh-cn/md_doc_tutorial_8zh-cn.html
这里是原作者对rapidjson代码的剖析:http://miloyip.com/rapidjson/
我之前的项目使用的是jsoncpp,最近在把解析json的代码交叉编译到iOS设备的时候,偶尔会出现crash的情况。虽然经过检查是代码写的有问题,不是jsoncpp的问题,在解决问题过程中尝试了rapidjson这个库,并顺便对比了一下jsoncpp和rapidjson对我项目中json文件的解析速度。
代码
三方库下载
头文件包含
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "rapidjson/document.h"
读
string car_json = ori_json + "/" + filename + ".json";
ifstream in_file(car_json);
if(!in_file.is_open()) return -1;
ostringstream in_file_str;
in_file_str<<in_file.rdbuf();
rapidjson::Document document;
document.Parse(in_file_str.str().c_str());
if(!document.IsObject()) return -1;
rapidjson::Value &dataArray = document["objects"];
if(dataArray.IsArray()){
for(rapidjson::SizeType i=dataArray.Size()-1; i>=0; i--){
const rapidjson::Value& object = dataArray[i];
if(std::atoi(object["label"].GetString()) == 0){
}else if(std::atoi(object["label"].GetString()) == 1){
}else if(std::atoi(object["label"].GetString()) == 2){
}
}
}
写
void test()
{
//read json
string updateInfo = "{\"UpdateInfo\":[{\"url\":\"aaaa.ipa\",\"platform\":\"ios\"}]}";
rapidjson::Document doc;
doc.Parse<0>(updateInfo.c_str());
rapidjson::Value &dataArray = doc["UpdateInfo"];
if (dataArray.IsArray())
{
for (int i = 0; i < dataArray.Size(); i++)
{
const rapidjson::Value& object = dataArray[i];
string url = object["url"].GetString();
string platform = object["platform"].GetString();
}
}
//write json
rapidjson::Document document;
document.SetObject();
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
rapidjson::Value array(rapidjson::kArrayType);
for (int i = 0; i < 10; i++)
{
rapidjson::Value object(rapidjson::kObjectType);
object.AddMember("id", 1, allocator);
object.AddMember("name", "test", allocator);
object.AddMember("version", 1.01, allocator);
object.AddMember("vip", true, allocator);
object.SetInt(i);
array.PushBack(object, allocator);
}
document.AddMember("title", "PLAYER INFO", allocator);
document.AddMember("players", array, allocator);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
document.Accept(writer);
auto out = buffer.GetString();
log("out: %s", out);
}
参考
https://www.cnblogs.com/skying555/p/9633785.html
https://cloud.tencent.com/developer/article/1344269
有用函数
#include <dirent.h>
#include <vector>
#include <string.h>
void GetFileNames(const std::string path, std::vector<std::string> &filenames, const std::string suffix = "") {
DIR *pDir;
struct dirent *ptr;
if (!(pDir = opendir(path.c_str())))
return;
while ((ptr = readdir(pDir)) != 0) {
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
std::string file = path + "/" + ptr->d_name;
if (opendir(file.c_str())) {
GetFileNames(file, filenames, suffix);
} else {
if (suffix == file.substr(file.size() - suffix.size())) {
filenames.push_back(file);
}
}
}
}
closedir(pDir);
}
#include<vector>
void SplitString(std::string str, const char& split, std::vector<std::string>& v_str){
std::stringstream sstr(str);
std::string token;
while(getline(sstr, token, split)){
v_str.push_back(token);
}
}
void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c)
{
std::string::size_type pos1, pos2;
pos2 = s.find(c);
pos1 = 0;
while(std::string::npos != pos2)
{
v.push_back(s.substr(pos1, pos2-pos1));
pos1 = pos2 + c.size();
pos2 = s.find(c, pos1);
}
if(pos1 != s.length())
v.push_back(s.substr(pos1));
}