既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
- { }
"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编码进行读取!
9. 这是补充的内容:[ [ ], [ ] ]
这是2021年11月11日补充的内容。偶然间在csdn问答模块看到有人问这种数组包含数组的Json方式该如何实现,于是我点开自己这一篇博客一看,发现没有记录这种做法,于是乎今天将这种用法补充一下!
在这里创建好的json,下面也有对应的解析讲解!
那么,这种数组包含数组的效果该如何实现呢?
"color": [
[ "black", "white" ],
[ "red", "greed" ]
]
代码实现上述效果:
// 定义 [ ] 对象
QJsonArray colorArray;
// 定义 [ ] 对象
QJsonArray colorArray1;
// 往数组中添加元素
colorArray1.append("black");
colorArray1.append("white");
// 定义 [ ] 对象
QJsonArray colorArray2;
// 往数组中添加元素
colorArray2.append("red");
colorArray2.append("greed");
colorArray.append(colorArray1);
colorArray.append(colorArray2);
把代码写好后,编译运行,会在自己的项目路径中创建一个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();
注意编码啊!
2. 将字符串解析成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值,再转换类型就可以拿到数据了。
6. 解析数组 [ ]
也就是解析下图内容:
解析代码:
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();
}
}
解析运行结果如下:
- 解析 数组 中 数组 [ [ ] [ ] ]
对应上面补充内容的解析操作!
也就是解析下图内容:
解析代码:
// 根键获取值
QJsonValue colorValue = rootObject.value("color");
// 判断类型是否是数组类型
if (colorValue.type() == QJsonValue::Array) {
// 转换成数组类型
QJsonArray colorArray = colorValue.toArray();
// 遍历数组
for (int i = 0; i < colorArray.count(); i++) {
// 获取数组的第一个元素,类型是QJsonValue
QJsonValue colorValueChild = colorArray.at(i);
// 判断是不是数组类型
if (colorValueChild.type() == QJsonValue::Array) {
// 转换成数组类型
QJsonArray colorArr = colorValueChild.toArray();
for (int i = 0; i < colorArr.size(); i++) {
QJsonValue color = colorArr.at(i);
qDebug() << "color = " << color.toString();
}
}
}
}
四、修改Json
修改的过程就是:将数据从文件中读取出来,解析成QJsonDocument对象后,在获取跟对象{ },通过跟对象在获取其他的对象{}或者数组[],修改后,再赋值给跟对象{},达到替换效果,也就是修改了,最后再写入文件即可!
- 读取数据解析成QJsonDocument代码省略,跟上面一样
- 获取根节点对象
// 获取根 { }
QJsonObject rootObj = doc.object();
- 修改属性
// 修改name属性
rootObj["name"] = "老李";
rootObj["vip"] = false;
修改前:
修改后:
4. 修改数组 [ ] 中的元素
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;
}
修改前:
修改后:
5. 修改 { } 中的值
QJsonValue interestValue = rootObj.value("interest");
if (interestValue.type() == QJsonValue::Object) {
QJsonObject interestObject = interestValue.toObject();
interestObject["badminton"] = "乒乓球";
interestObject["basketball"] = "足球";
rootObj["interest"] = interestObject;
}
修改前:
修改后:
6. 修改 { { } } 中的值
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;
}
修改前:
修改后:
7. 修改 [ { } ]
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.replace(0, obj1);
likeArray.replace(1, obj2);
rootObj["like"] = likeArray;
}
修改前:
修改后:
8. 写入文件
最后,再将跟节点对象{ }重新设置给QJsonDocument对象,在重新写入文件即可!
// 将object设置为本文档的主要对象
doc.setObject(rootObj);
// 重写打开文件,覆盖原有文件,达到删除文件全部内容的效果
QFile writeFile("../Json/js.json");
if (!writeFile.open(QFile::WriteOnly | QFile::Truncate)) {
qDebug() << "can't open error!";
return;
}
// 将修改后的内容写入文件
QTextStream wirteStream(&writeFile);
wirteStream.setCodec("UTF-8"); // 设置读取编码是UTF8
wirteStream << doc.toJson(); // 写入文件
writeFile.close(); // 关闭文件
五、删除Json
删除跟修改类似的,使用跟节点对象找到对象{}或者数组[]后,使用remove函数指定键参数进行删除!
- 读取数据解析成QJsonDocument代码省略,跟上面一样
- 获取根节点对象
// 获取根 { }
QJsonObject rootObj = doc.object();
- 删除属性
// 删除age
rootObj.remove("age");
- 删除数组[]中的元素
QJsonValue colorValue = rootObj.value("color");
if (colorValue.type() == QJsonValue::Array) {
QJsonArray colorArray = colorValue.toArray();
// 删除数组中索引为1的值
colorArray.removeAt(1);
// 赋值覆盖原有数组属性
rootObj["color"] = colorArray;
}
删除前:
删除后:
5. 删除 { } 中的值
QJsonValue interestValue = rootObj.value("interest");
if (interestValue.type() == QJsonValue::Object) {
QJsonObject interestObject = interestValue.toObject();
// 删除键为basketball的属性元素
interestObject.remove("basketball");
rootObj["interest"] = interestObject;
}
删除前:
删除后:
6. 删除 { { } } 中的值
QJsonValue languagesValue = rootObj.value("languages");
if (languagesValue.type() == QJsonValue::Object) {
QJsonObject languagesObj = languagesValue.toObject();
// 删除键为serialTwo的对象 { }
languagesObj.remove("serialTwo");
rootObj["languages"] = languagesObj;
}
删除前:
删除后:
7. 删除 [ ] 中的 { }
QJsonValue likeValue = rootObj.value("like");
if (likeValue.type() == QJsonValue::Array) {
QJsonArray likeArray = likeValue.toArray();
// 删除索引为1数组中的值
likeArray.removeAt(1);
rootObj["like"] = likeArray;
}
删除前:
删除后:
8. 删除 对象 { } 与 删除 数组 [ ]
// 删除 [ ]
rootObj.remove("color");
// 删除 { }
rootObj.remove("interest");
删除后就没有啦!
9. 写入文件
最后,再将跟节点对象{ }重新设置给QJsonDocument对象,在重新写入文件即可!
与上同,这里就不写下代码了!
六、全部代码
我这代码使用VS2017新建一个QT空项目写出来的!
指定编码
#pragma execution_character_set(“utf-8”) // qt支持显示中文
#include <QCoreApplication>
#include <QJsonObject> // { }
#include <QJsonArray> // [ ]
#include <QJsonDocument> // 解析Json
#include <QJsonValue> // int float double bool null { } [ ]
#include <QJsonParseError>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#pragma execution\_character\_set("utf-8") // qt支持显示中文
// 封装Json
void createJson() {
/\*
\* "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);
// 将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();
}
// 解析Json
void analysisJson() {
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();
/\* 解析Json \*/
// 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();
// 解析对象 { }
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();
}
// 解析数组 [ ]
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 likeValueChild = likeArray.at(i);
if (likeValueChild.type() == QJsonValue::Object) {
QJsonObject likeObj = likeValueChild.toObject();
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();
![img](https://img-blog.csdnimg.cn/img_convert/9d719ffc0865b21df1af7c4f205f192b.png)
![img](https://img-blog.csdnimg.cn/img_convert/e63f30871aaf1f4882d4b5fa8a78b8b3.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
ikeArray.count(); i++) {
QJsonValue likeValueChild = likeArray.at(i);
if (likeValueChild.type() == QJsonValue::Object) {
QJsonObject likeObj = likeValueChild.toObject();
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();
[外链图片转存中...(img-gzpl5ZNF-1715789806605)]
[外链图片转存中...(img-zRazXmis-1715789806605)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**