Json
- 简介
- Json下载
- Json::Value 数据对象类
- Json 序列化/反序列化的介绍
- Json 的序列化类
- 低版本
- 高版本
- Json 的反序列化类
- 低版本
- 高版本
- Json序列化操作
- Json反序列化操作
简介
json 是一种数据交换格式,采用独立于编程语言的文本格式来存储和表示的数据。
Json下载
使用 Json 需要先下载对应的 Json库,下载步骤如下:
- 先更新 yum 源的缓存:
yum makecache fast
- 下载 json 库
sudo yum -y install jsoncpp-devel
在下载好 json 库后,使用这个库时需要包含头文件:#include <jsoncpp/json/json.h>
由于 json库是第三方库,在 g++ 编译阶段是需要告诉编译器编译时要找对应的 json库,对此编译时需要带上 -ljsoncpp
选项:
g++ -o test test.cc -std=c++11 -ljsoncpp #test.cc举例文件
Json::Value 数据对象类
Value 是 json 提供的一个数据类型,通过这个数据类型定义的对象,我们可以调用其中对应的成员函数。
下面是Value数据对象类的成员函数:
class Json::Value
{
Value &operator=(const Value &other); //表示任意的数据都可以进行赋值
Value& operator[](const std::string& key);//使用字符串进行赋值 va["姓名"]=“小明";
Value& operator[](const char* key);
Value removeMember(const char* key);//删除数据
const Value& operator[](ArrayIndex index) const; //val["成绩"][0]
Value& append(const Value& value);//添加数组元素, va1["成绩"].append(88);
ArrayIndex size()const;//获取数组元素个数, va["成绩"].size()
//转对应的数据类型
std::string asstring( const;//转string类型, string name =val["name"l.asstring();
const char* ascstring();//转char*类型
Int asIntO const;//转int类型
float asFloat() const;//转float类型
bool asBool()const;//转 bool 类型
};
Json 序列化/反序列化的介绍
- 序列化是指将编程语言中的数据(如对象、数组等)转换成 Json 格式的字符串
- 反序列化是序列化的逆过程,将序列化的 Json 字符串恢复为原来的数据
Json 的序列化类
Json 序列化类有两个版本,分别是 高版本的 Json 序列化类 和 低版本的 Json 序列化的类。
两个版本的区别就是:低版本使用起来比较容易上手,但是由于版本的原因,使用低版本会出现警告的提示;使用高版本就不会。
低版本
其中,低版本的 Json序列化中提供了两个序列化的接口,分别是:Fastwriter
和 styledwriter
//父类
class JSON_API Writer
{
virtual std::string write(const Value& root)= 0; //纯虚函数
}
//子类
class JSoN_API Fastwriter :public writer
{
virtual std::string write(const Value& root); //root表示Json数据对象
}
class JSoN_API styledwriter :public writer
{
virtual std::string write(const Value& root);//root表示Json数据对象
}
Fastwriter
和 styledwriter
类都继承了Writer
类,都对父类的 write
虚函数函数进行了重写,构成了多态。这两个类都是将 Json::Value 数据对象转换为字符串。
两者之间的不同的区别就是:在调用 StyleWriter 类将数据对象转换为字符串时会增加缩进和换行符,使生成的JSON字符串具有良好的可读性,方便调试;而 Fastwriter 是将数据对象转换为字符串就结束了。
高版本
在高版本的 Json序列化中只有一个类:StreamwriterBuilder
//父类
class JSON_API streamWriter
{
virtual int write(Value const& root, std::ostream* sout)= 0;//root表示Json数据对象,sout表示将数据显示到输出
}
//子类
class JSON_API StreamwriterBuilder : public streamwriter::Factory
{
virtual streamwriter* newstreamWriter() const;
}
高版本使用起来有点麻烦,在定义序列化对象时,需要用指针的方式来接收 StreamwriterBuilder
类对象调用 newstreamWriter
成员函数来返回的streamWriter *
的指针类型的对象。
序列化定义对象示例:
void test()
{
StreamwriterBuilder builder; //定义StreamwriterBuilder对象
std::unique_ptr<Json::streamWriter> writer(builder.newstreamWriter()); //定义序列化对象writer
}
通过高版本来定义序列化对象可以很好避免了版本问题,不会出现告警的提示。
Json 的反序列化类
与 Json 序列化类一样,Json 反序列化类也有高低版本之分。低版本使用起来很简便容易,但是有告警出现;高版本使用比较麻烦,但是解决了告警出现。
低版本
class JSON_API Reader
{
bool parse(const std::string& document, Value& root, bool collectcomments = true);
}
参数介绍:
- document:表示要转换的Json格式的字符串
- root:将转换的内容存入到数据对象中
- 返回值:转换成功返回 true,失败返回 false
collectcomments 参数一般不需要设置,默认缺省即可。
高版本
//父类
class JSON_API CharReader
{
virtual bool parse(char const* beginDoc, char const* endDoc,Value* root,std::string*errs)=0;
}
//子类
class JSoN_API CharReaderBuilder : public charReader::Factory
{
virtual charReader* newcharReader() const;
}
使用方式如同序列化高版本那般,需要先定义 CharReaderBuilder
对象,通过这个对象去构建 charReader
对象指针,进而去使用 parse
方法。
parse 参数介绍:
- beginDoc:指向需要转换的Json格式的字符串起始位置
- endDoc:指向需要转换的Json格式的字符串末尾位置
- root:将转换的内容存入到数据对象中
- errs:表示转换失败会将失败信息打印到标准错误中
- 返回值:转换成功返回 true,失败返回 false
Json序列化操作
来看这样的一个类:
class Request
{
public:
Request(){}
Request(int x, int y, char op): _x(x), _y(y), _op(op)
{}
~Request() {}
public:
int _x;
int _y;
char _op;
};
通过上面提供的类,将对应的成员变量进行序列化操作:
- 先定义 Value 数据对象
Json::Value root; //root对象通过重载[]的方式,可以用来接收任意的 key/val 类型
- 调用 root 对象的成员函数,进行 key/val 赋值
- 定义序列化对象:
FastWrite
- 调用
FastWrite
定义对象的成员函数:write
完成序列化操作
具体的操作如下示例:
class Request
{
public:
//其他成员函数...
//序列化
bool Serialize(std::string *outStr)
{
Json::Value root;
//接收key/val类型
root["x"] = _x;
root["y"] = _y;
root["op"] = _op;
Json::FastWrite writer; //writer用来序列化的对象
std::string outStr = writer.write(root); //将结构化数据转换为json字符串
return true;
}
public:
int _x;
int _y;
char _op;
};
下面是用 Json 高版本的序列化类举的例子:
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
const char *name = "张三";
int age = 18;
float score[] = {77, 88.8, 99.5};
Json::Value root;
root["姓名"] = name;
root["年龄"] = age;
root["成绩"].append(score[0]);
root["成绩"].append(score[1]);
root["成绩"].append(score[2]);
//序列化操作
Json::StreamWriterBuilder swb;
std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
std::stringstream ss;
sw->write(root, &ss);
//输出内容
std::cout << ss.str() << std::endl;
return 0;
}
Json反序列化操作
与序列化操作类似:
- 先定义 Value 数据对象
Json::Value root; //root对象通过重载[]的方式,可以用来接收任意的 key/val 类型
- 定义反序列化对象:
Reader
- 调用
Reader
定义对象的成员函数:parse
完成反序列化操作
Json::Reader reader;
reader.parse(str, root);//str是json串,parse函数是将json串转化为结构化数据
- 最后对原来的结构化数据进行赋值,完成反序列化的工作
具体的操作如下示例:
class Request
{
public:
//其他成员函数...
//反序列化
bool Deserialize(const std::string &isStr) //isStr是json串
{
Json::Value root;
Json::Reader reader;//reader用来反序列化的对象
reader.parse(isStr, root);//将json串转化为结构化数据
//进行结构化数据的赋值操作
_x = root["x"].asInt();
_y = root["y"].asInt();
_op = root["op"].asInt();
return true;
}
public:
int _x;
int _y;
char _op;
};
下面是用 Json 高版本的反序列化类举的例子:
int main()
{
std::string str = R"({"姓名":"张三", "年龄":20, "成绩":[59, 66.5, 77.5]})"; // 使用R"()"可以防止字符串内部符号出现歧义
Json::Value root;
// 反序列化操作
Json::CharReaderBuilder crb;
std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
std::string err;
bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), &root, &err);
if(ret == false)//解析失败
{
std::cout << "parse error : " << err << std::endl;
exit(-1);
}
//解析成功,输出内容
std::cout << "姓名:" << root["姓名"].asString() << std::endl;
std::cout << "年龄:" << root["年龄"].asInt() << std::endl;
int sz = root["成绩"].size();
std::cout << "成绩:";
for(int i = 0; i < sz; i++)
{
std::cout << root["成绩"][i] << " ";
}
std::cout << std::endl;
return 0;
}
Json 下载与简单使用就介绍到这里,喜欢的老铁可以点个赞加关注。