Qt 操作Json格式文件(创建插入解析修改删除)
Posted cpp_learner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 操作Json格式文件(创建插入解析修改删除)相关的知识,希望对你有一定的参考价值。
花了几天时间研究Qt如何操作Json文件,也是有一点心得,现在记录下来分享!
为什么要学习Json呢?Json是一个轻量级数据存储文件,其里面使用了大量的字符进行存储数据。JSON 是存储和交换文本信息的语法,类似 XML。JSON 比 XML 更小、更快,更易解析。
JSON 是一种编码来自 javascript 的对象数据的格式,但现在已广泛用作互联网上的数据交换格式。
Qt 中的 JSON 支持提供了易于使用的C++ API 来解析、修改和保存 JSON 数据。
当然,我学习Json,主要是因为我的上一篇博客中学习了Qt的Socket编程,个人觉得,如果是需要在TCP与UDP进行数据传送的话,使用Json文件传输效率会比较高吧…个人理解,不喜勿喷!
所以呢,今天带来一篇,使用Qt操作Json格式文件的博客,供大家参考、借鉴!
一、准备工作
VS编译器创建项目时,勾选Core项
QT编译器需要在.pro文件中 QT += Core
操作Json文件所需要用到的类:
类 | 类说明 |
---|---|
QJsonDocument | 读写JSON文档 |
QJsonObject | 封装JSON对象 { } |
QJsonArray | 封装JSON数组 [ ] |
QJsonValue | 封装JSON值 int,float,double,bool,{ },[ ]等 |
QJsonParseError | 报告JSON处理过程中出现的错误 |
操作Json文件所需要用到的头文件:
#include < QJsonObject > // { }
#include < QJsonArray > // [ ]
#include < QJsonDocument > // 解析Json
#include < QJsonValue > // int float double bool null { } [ ]
#include < QJsonParseError >
下图是这篇博客所操作的JSON文件:
二、封装Json
-
{ }
"interest": { "basketball": "篮球", "badminton": "羽毛球" },
代码实现上述效果:
// 定义 { } 对象 QJsonObject interestObj; // 插入元素,对应键值对 interestObj.insert("basketball", "篮球"); interestObj.insert("badminton", "羽毛球");
-
[ ]
"color": [ "black", "white"],
代码实现上述效果:
// 定义 [ ] 对象 QJsonArray colorArray; // 往数组中添加元素 colorArray.append("black"); colorArray.append("white");
-
[ { } { } ]
"like": [ { "game": "三国杀", "price": 58.5 }, { "game": "海岛奇兵", "price": 66.65 } ],
代码实现上述效果:
// 定义 { } 对象 QJsonObject likeObject1; likeObject1.insert("game", "三国杀"); likeObject1.insert("price", 58.5); QJsonObject likeObject2; likeObject2.insert("game", "海岛奇兵"); likeObject2.insert("price", 66.65); // 定义 [ ] 对象 QJsonArray likeArray; likeArray.append(likeObject1); likeArray.append(likeObject2);
-
{ { } { } }
"languages": { "serialOne": { "language": "汉语", "grade": 10 }, "serialTwo": { "language": "英语", "grade": 6 } },
代码实现上述效果:
// 定义 { } 对象 QJsonObject language1; language1.insert("language", "汉语"); language1.insert("grade", 10); QJsonObject language2; language2.insert("language", "英语"); language2.insert("grade", 6); QJsonObject languages; // 将{ } 插入 { } 中 languages.insert("serialOne", language1); languages.insert("serialTwo", language2);
-
定义根节点 也即是最外层 { }
// 定义根节点 也即是最外层 { } QJsonObject rootObject;
-
将上面定义的{ } 与 [ ] 都插入到跟节点{ }中
// 插入元素 rootObject.insert("name", "老王"); rootObject.insert("age", 26); rootObject.insert("interest", interestObj); rootObject.insert("color", colorArray); rootObject.insert("like", likeArray); rootObject.insert("languages", languages); rootObject.insert("vip", true); rootObject.insert("address", QJsonValue::Null);
-
实例化QJsonDocument对象
// 将json对象里的数据转换为字符串 QJsonDocument doc; // 将object设置为本文档的主要对象 doc.setObject(rootObject);
-
Json字符串保存到json文件里
QFile file("../Json/js.json"); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "can't open error!"; return; } QTextStream stream(&file); stream.setCodec("UTF-8"); // 设置写入编码是UTF8 // 写入文件 stream << doc.toJson(); file.close();
这里需要注意的是,我们写入文件时,指定的编码是UTF8,所以在读取出来时也需要使用UTF8编码进行读取!
把代码写好后,编译运行,会在自己的项目路径中创建一个JSON文件,并写入内容,文件内容如下:
顺序可能有点乱,但是不妨碍我们阅读与下面解析!
三、解析Json
解析根据上图进行!
在使用JSON对象或者JSON数组对象得到对应的value之后,该value值并不是最总的数据类型,而是一个QJsonValue类型的属性,我们必须通过该对象判断该类型的实际类型,然后在将其转换为对应的数据类型。
可以使用下面表格的方法,也可以使用代码中的方法进行判断,
类型判断相关成员方法:
方法 | 解释 |
---|---|
bool isArray() const | 是否为json数组 |
bool isBool() const | 是否为布尔类型 |
bool isDouble() const | 是否为浮点类型 |
bool isNull() const | 是否为空 |
bool isObject() const | 是否为json对象 |
bool isString() const | 是否为字符串类型 |
-
打开文件,读取全部内容
QFile file("../Json/js.json"); if (!file.open(QFile::ReadOnly | QFile::Text)) { qDebug() << "can't open error!"; return; } // 读取文件的全部内容 QTextStream stream(&file); stream.setCodec("UTF-8"); // 设置读取编码是UTF8 QString str = stream.readAll(); file.close();
注意编码啊!
-
将字符串解析成QJsonDocument对象
// QJsonParseError类用于在JSON解析期间报告错误。 QJsonParseError jsonError; // 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。 // 如果解析成功,返回QJsonDocument对象,否则返回null QJsonDocument doc = QJsonDocument::fromJson(str.toUtf8(), &jsonError); // 判断是否解析失败 if (jsonError.error != QJsonParseError::NoError && !doc.isNull()) { qDebug() << "Json格式错误!" << jsonError.error; return; }
-
获取根 { }
QJsonObject rootObj = doc.object();
-
根据键获取值
// 根据键获取值 QJsonValue nameValue = rootObj.value("name"); qDebug() << "name = " << nameValue.toString(); QJsonValue ageValue = rootObj.value("age"); qDebug() << "age = " << ageValue.toInt(); // 解析 bool类型 QJsonValue vipValue = rootObj.value("vip"); qDebug() << "vip = " << vipValue.toBool(); // 解析 null类型 QJsonValue addressValue = rootObj.value("address"); if (addressValue.type() == QJsonValue::Null) { qDebug() << "address = " << "null"; }
-
解析对象 { }
也就是解析下图内容:
解析代码:
QJsonValue interestValue = rootObj.value("interest"); // 判断是否是object类型 if (interestValue.type() == QJsonValue::Object) { // 转换为QJsonObject类型 QJsonObject interestObj = interestValue.toObject(); QJsonValue basketballValue = interestObj.value("basketball"); qDebug() << "basketball = " << basketballValue.toString(); QJsonValue badmintonValue = interestObj.value("badminton"); qDebug() << "badminton = " << badmintonValue.toString(); }
通过value函数根据键获取到一个QJsonValue 类型数据,然后进行判断是否是对应类型,然后转换成对应类型,就可以使用value函数进行获取QJsonValue值,再转换类型就可以拿到数据了。
-
解析数组 [ ]
也就是解析下图内容:
解析代码:QJsonValue colorValue = rootObj.value("color"); // 判断是否是Array类型 if (colorValue.type() == QJsonValue::Array) { // 转换为QJsonArray类型 QJsonArray colorArray = colorValue.toArray(); for (int i = 0; i < colorArray.size(); i++) { QJsonValue color = colorArray.at(i); qDebug() << "color = " << color.toString(); } }
-
解析数组中的对象 [ { } ]
也就是解析下图内容:
解析代码:// 根键获取值 QJsonValue likeValue = rootObj.value("like"); // 判断类型是否是数组类型 if (likeValue.type() == QJsonValue::Array) { // 转换成数组类型 QJsonArray likeArray = likeValue.toArray(); // 遍历数组 for (int i = 0; i < likeArray.count(); i++) { // 获取数组的第一个元素,类型是QJsonValue QJsonValue likeValueChild = likeArray.at(i); // 判断是不是对象类型 if (likeValueChild.type() == QJsonValue::Object) { // 转换成对象类型 QJsonObject likeObj = likeValueChild.toObject(); // 最后通过value函数就可以获取到值了,解析成功! QJsonValue gameLikeValue = likeObj.value("game"); qDebug() << "game = " << gameLikeValue.toString(); QJsonValue priceLikeValue = likeObj.value("price"); qDebug() << "price = " << priceLikeValue.toDouble(); } } }
-
解析 对象 中 对象 { { } }
也就是解析下图内容:
解析代码:// 根据建获取值 QJsonValue languagesValue = rootObj.value("languages"); // 判断是不是对象类型 if (languagesValue.type() == QJsonValue::Object) { // 转换成对象类型 QJsonObject languagesObj = languagesValue.toObject(); // 根据建获取值 QJsonValue serialOneValue = languagesObj.value("serialOne"); // 判断是不是对象类型 if (serialOneValue.type() == QJsonValue::Object) { // 转换成对象类型 QJsonObject serialOneObj = serialOneValue.toObject(); // 根据建获取值 QJsonValue languageValue = serialOneObj.value("language"); // 最后转换成对应类型就解析出来了! qDebug() << "language = " << languageValue.toString(); QJsonValue gradeValue = serialOneObj.value("grade"); qDebug() << "grade = " << gradeValue.toInt(); } QJsonValue serialTwoValue = languagesObj.value("serialTwo"); if (serialTwoValue.type() == QJsonValue::Object) { QJsonObject serialTwoObj = serialTwoValue.toObject(); QJsonValue languageValue = serialTwoObj.value("language"); qDebug() << "language = " << languageValue.toString(); QJsonValue gradeValue = serialTwoObj.value("grade"); qDebug() << "grade = " << gradeValue.toInt(); } }
解析运行结果如下:
四、修改Json
修改的过程就是:将数据从文件中读取出来,解析成QJsonDocument对象后,在获取跟对象{ },通过跟对象在获取其他的对象{}或者数组[],修改后,再赋值给跟对象{},达到替换效果,也就是修改了,最后再写入文件即可!
-
读取数据解析成QJsonDocument代码省略,跟上面一样
-
获取根节点对象
// 获取根 { } QJsonObject rootObj = doc.object();
-
修改属性
// 修改name属性 rootObj["name"] = "老李"; rootObj["vip"] = false;
修改前:
修改后:
-
修改数组 [ ] 中的元素
QJsonValue colorValue = rootObj.value("color"); if (colorValue.type() == QJsonValue::Array) { QJsonArray colorArray = colorValue.toArray(); // 修改数组中的值 colorArray.replace(0, "blue"); colorArray.replace(1, "green"); // 赋值覆盖原有数组属性 rootObj["color"] = colorArray; }
修改前:
修改后:
-
修改 { } 中的值
QJsonValue interestValue = rootObj.value("interest"); if (interestValue.type() == QJsonValue::Object) { QJsonObject interestObject = interestValue.toObject(); interestObject["badminton"] = "乒乓球"; interestObject["basketball"] = "足球"; rootObj["interest"] = interestObject; }
修改前:
修改后:
-
修改 { { } } 中的值
QJsonValue languagesValue = rootObj.value("languages"); if (languagesValue.type() == QJsonValue::Object) { QJsonObject languagesObj = languagesValue.toObject(); // 找到内部第一个 { } QJsonValue serialOneValue = languagesObj.value("serialOne"); if (serialOneValue.type() == QJsonValue::Object) { QJsonObject serialOneObj = serialOneValue.toObject(); serialOneObj["grade"] = "20"; languagesObj["serialOne"] = serialOneObj; } // 找到内部第二个 { } QJsonValue serialTwoValue = languagesObj.value("serialTwo"); if (serialTwoValue.type() == QJsonValue::Object) { QJsonObject serialTwoObj = serialTwoValue.toObject(); serialTwoObj["grade"] = "10"; serialTwoObj["language"] = "粤语"; languagesObj["serialTwo"] = serialTwoObj; } rootObj["languages"] = languagesObj; }
修改前:
修改后:
-
修改 [ { } ]
QJsonValue likeValue = rootObj.value("like"); if (likeValue.type() == QJsonValue::Array) { QJsonArray likeArray = likeValue.toArray(); // 根据索引获得对应{ } QJsonObject obj1 = likeArray[0].toObject(); obj1["game"] = "欢乐斗地主"; obj1["price"] = 88.8; QJsonObject obj2 = likeArray[1].toObject(); obj2["game"] = "欢乐斗牛"; obj2["price"] = 77.7; // 替换覆盖 likeArray.repl
以上是关于Qt 操作Json格式文件(创建插入解析修改删除)的主要内容,如果未能解决你的问题,请参考以下文章
C/C++ 使用cjson库 操作Json格式文件(创建插入解析修改删除)
C/C++ 使用 tinyxml库 操作XML格式文件(创建插入删除修改解析)