Qt中JSON字符串的使用
JSON是一种对源自Javascript的对象数据进行编码的格式,但现在广泛用作互联网上的数据交换格式。有一种应用场景:存储变化的坐标对。存储JSON数组字符串即可。
从 Qt 5.0 就开始提供处理 Json 数据的操作支持,Qt中的JSON支持提供了一个易于使用的C++ API来解析,修改和保存JSON数据。
Qt中所有的 JSON 类都是基于值的隐式共享类(隐式共享类的意思是只要它没有被修改,它就与创建它的文档共享数据)。
QJsonDocument 是一个封装完整JSON文档的类,可以从基于UTF-8编码的文本表示和Qt自己的二进制格式来对该文档进行读写操作。使用 QJsonDocument::fromJson() 可以将JSON文档从基于文本的表示形式转换为 QJsonDocument,使用 QJsonDocument::toJson() 可以将其转换回文本形式。解析器非常快速和有效,并可以使用 QJsonDocument::toBinaryData() 将 JSON 转换为Qt使用的二进制表示。
因为 QJsonObject 和 QJsonArray 这两个对象中的数据是不能直接转换为字符串类型的,如果要进行数据传输或者数据的持久化保存,需要对数据进行序列化和反序列化操作。
QJsonObject 或者 QJsonArray 序列化为 字符串
1.创建 QJsonDocument 对象
QJsonDocument::QJsonDocument(const QJsonObject &object); //个人常用
QJsonDocument::QJsonDocument(const QJsonArray &array);
QJsonDocument::QJsonDocument(const QJsonDocument &other); //几乎不用QJsonDocument::QJsonDocument(); //或者创建一个空对象,使用以下两个方法设置数据
QJsonDocument::setArray(const QJsonArray &array);
QJsonDocument::setObject(const QJsonObject &object);
2.将文件对象中的数据进行序列化
QByteArray QJsonDocument::toBinaryData() const; //二进制格式的json字符串
QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const; //文本格式
3.使用得到的字符串进行数据传输,或者磁盘文件持久化
字符串 反序列化为 QJsonObject 或者 QJsonArray
1.将通过网络通信或磁盘文件读取得到的 Json 格式字符串转换为 QJsonDocument 对象
QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR); //个人常用
QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation = Validate);
QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation = Validate)
QJsonDocument QJsonDocument::fromVariant(const QVariant &variant)
2.将文档对象转换为 Json 数组 或 Json 对象
bool QJsonDocument::isArray() const; //判断文档对象中存储的数据是不是数组
bool QJsonDocument::isObject() const //判断文档对象中存储的数据是不是json对象
QJsonObject QJsonDocument::object() const; //文档对象中的数据转换为json对象
QJsonArray QJsonDocument::array() const; //文档对象中的数据转换为json数组
3.通过调用 QJsonArray , QJsonObject 类提供的 API 读取存储在 QJsonDocument 对象中的数据
QJsonValue 类用JSON封装了一个值,该值在内部是严格类型的,与QVariant相反,它不会尝试进行任何隐式类型转换。这意味着转换为不存储在值中的类型将返回一个默认的构造返回值。值的类型可以是如下六种基本数据类型:
布尔类型 QJsonValue::Bool
浮点类型(包括整形) QJsonValue::Double
字符串类型 QJsonValue::String
Json 数组类型 QJsonValue::Array
Json 对象类型 QJsonValue::Object
空值类型 QJsonValue::Null
1.测试读写的 test.json 文件内容(文件路径 E:\test.json)
{"FirstName": "Fu","LastName": "Cong","Age": 24,"Address": {"Street": "首创悦榕汇","City": "BeiJing","Country": "BeiJing"},"Phone numbers": ["+44 12345","+44 678910"]}
2.所需要的头文件
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QFile>
#include <QDebug>
3.写 Json 文件接口实现
void writeJson()
{QJsonObject obj_root;obj_root.insert("FirstName","Fu");obj_root.insert("LastName","Cong");obj_root.insert("Age",24);QJsonObject subObj_addr;subObj_addr.insert("Street","首创悦榕汇");subObj_addr.insert("City","BeiJing");subObj_addr.insert("Country","BeiJing");obj_root.insert("Address",subObj_addr);QJsonArray arr_phone;arr_phone.append("+44 12345");arr_phone.append("+44 678910");obj_root.insert("Phone numbers",arr_phone);QJsonDocument jsonDocu(obj_root);QByteArray jsonData = jsonDocu.toJson();QFile file("E:\\test.json");if(file.open(QIODevice::WriteOnly)){file.write(jsonData);file.close();}
}
4.读 Json 文件接口实现
void readJson()
{QFile file("E:\\test.json");QByteArray jsonData;if(file.open(QIODevice::ReadOnly)){jsonData = file.readAll();file.close();}QJsonDocument jsonDocu = QJsonDocument::fromJson(jsonData);if(jsonDocu.isObject()){QJsonObject obj_root = jsonDocu.object();QStringList keys = obj_root.keys();for(auto key : keys){QJsonValue value = obj_root.value(key);if(value.isString()){qDebug() << key <<": "<< value.toString();}else if(value.isDouble()){qDebug() << key <<": "<< value.toInt();}else if(value.isArray()){QJsonArray arr = value.toArray();for(int i = 0; i < arr.count(); ++i){if(arr.at(i).isString()){qDebug() << key <<": "<< arr.at(i).toString();}//这里就不判断是否为其它类型了,因为测试文件已知为字符串,要写也和上面类似,无限套娃}}else if(value.isObject()){QJsonObject subObj = value.toObject();QStringList subKeys = subObj.keys();for(auto subKey : subKeys){QJsonValue subValue = subObj.value(subKey);if(subValue.isString()){qDebug() << subKey <<": "<< subValue.toString();}//这里就不判断是否为其它类型了,因为测试文件已知为字符串,要写也和上面类似,无限套娃}}}}
}
该文章会更新,欢迎大家批评指正。
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器