当前位置:   article > 正文

Qt JSON详解一

qt json

1、Json介绍:


1.1 Json的定义


JSON(JavaScrip Object Notation)是一种轻量级的数据交换格式。它基于ECMAScript(欧洲计算机协会订制的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。易于人阅读和缩写,同时也易于机器解析和生成,并有效地提升网络传输效率。

简述:Json是一种数据格式,和语言无关,什么语言中都可以使用Json。基于这种通用的数据格式,一般处理两方面的任务:

        1.组织数据(数据序列化),用于数据的网络传输。

        2.组织数据(数据序列化),写磁盘文件实现数据的持久化存储(一般.json作为作为文件后缀)

(什么时候需要数据持久化到磁盘?记住用户名、密码,简单存储到磁盘文件,通过加载本地配置文件,当窗口显示的时候就会加载配置文件,而不是读取磁盘内容,用户体验会更好。)

1.2 Json的数据格式


Json中主要有两种数据格式:Json数组和Json对象,并且这两种格式可以交叉嵌套使用,下面一次介绍这两种数据格式:

1.2.1 Json数组:


Json数组使用[]表示,[]里边是元素,元素和元素之间使用“,”间隔开,最后一个元素后边没有逗号,一个Json数组中支持同时存在多种不同类型的成员,包括:整型、浮点、字符串、布尔类型、json数组、json对象、空值-null。由此可见Json数组比起c/c++数组灵活很多。

字符串要写到双引号(“”)里边。

Json数组中嵌套Json数组,父子关系

Json数组嵌套Json对象,Json对象可以嵌套Json数组

(1)Json数组中的元素数据类型一致

[1, 2, 3]  //整型
["哈哈","hehe","yiyi"]   //字符串


(2)Json数组中的元素数据类型不一致

[1, 2, 3, true, false, "haha",null]


(3)Json数组中的数据嵌套使用

[
    ["cat", "狗狗", "河马", 1]//元素类型可以不一致
    [1, 3, 5, true]
]


(4)Json数组和Json对象嵌套

Json对象写入Json数组,数组是父节点,对象是子节点,Json对象下的Json对象是三级节点(Key:value)。"小明"是key值,{}是小明的value值,属性是键值对,

  1. [//外层是Json数组
  2. {//内层是Json对象
  3. "小明":{//属性键值对
  4. "age":19,
  5. "father":"大华",
  6. "sister":"小妹",
  7. "sister1":"大妹" //sister键值不可以重复
  8. }
  9. }
  10. ]

1.2.2 Json对象


Json对象使用{}来描述,每个Json对象可以存储若干个元素,每个元素对应一个键值对(key:value),元素和元素之间使用 , 间隔,最后一个元素后面没有 , 注意:

键值key,必须是字符串,位于同一层级的键值,不能重复(通过键值取出数据value)
value值的类型是可选的,整形,浮点型,字符串,json数组,json对象,空值-null(null) 
使用Json对象描述一个人的信息:

  1. {
  2. "NAME":"ACE",
  3. "Sex":"man",
  4. "Age":20,
  5. "Family":{
  6. "Father":"yiyi",
  7. "brother":["aa","bb","cc"]
  8. },
  9. "IsLive":"true"
  10. }

小细节:最后一个键值对没有逗号!!!

数据简单放数组,数据更复杂放Json对象,数组和对象的嵌套使用可以更加完整描述模型!!!

(温馨提示:逻辑关系确定清楚哦!!!)

1.2.3 注意事项


逗号(“,”)不能乱加,解析会出错。注意最后一个元素不能加逗号,否则解析出错。
键值不唯一,不能搜到到正确的value
数组持久化的过程中,后缀是".json"不是必须,但是推荐使用".json"
数据块只允许有一个根节点
错误示范:

2、Qt提供的Json类的使用


2.1 Json类介绍


2.1.1 四个常用Json类


2.1.2 四个常用Json类之间的关系 


JsonValue包装了Json支持的数据类型,JsonValue相当于一个箱子,可以重载JsonValue得到不同数据类型。 

2.2 QJsonValue


2.2.1 封装的数据类型6:

  • bool类型 QJsonValue::Bool
  • double类型 QJsonValue::Double
  • string类型 QJsonVale::String
  • array类型 QJsonValue.:Array
  • object类型 QJsonValue:Object
  • null了下 QJsonValue::Null

2.2.2 通过构造函数,将6种不同的类型统一。


类似于6种类型,放到一个箱子里面。

2.3 QJsonObject


封装了Json中的对象,在里边可以存储多个键值对,为了方便操作,键值为字符串类型,值为QJsonValue类型,关于这个类的使用类似,C++中STL类 QJsonObject内数据使用insert插入,根据key值,自动排序,底层红黑树,升序

2.3.1 创建空的Json对象


QJsonObject::QJsonObject() //构造空对象

2.3.2 将键值对添加到Json对象中



2.3.3 获取对象中,键值对个数



2.3.4 通过key取出value


传入key:得到QJsonObject对象,看看是什么,在使用to方法,得到原始数据


2.3.5 删除键值对


void QJsonObject::remove(const QString &key);
QJsonValue QJsonObject::take(const QString &key); //删除键值对后,返回value值


2.3.6 通过key进行查找


2.3.7 遍历方式3种


1.使用迭代器函数 
2.使用[],遍历,类似遍历数组,[]中是key 
3.先得到对象中所有的键值,在遍历键值列表,通过key得到value QStringList QJsonObject::keys() const;//得到当前Json对象中所有的key值
QStringList QJsonObject::keys() const;//得到当前Json对象中所有的key值


细节+++:QJsonObject在插入时会根据键值对数据升序排序,而QJsonArray不会根据键值排序,所以QJsonObject插入数据顺序完全由键值决定,因此插入顺序和排序顺序可能不同。但QJsonArray在插入数据的时候,数据存储在同一块连续内存中,所以插入顺序就是数据的排序顺序。

 2.4 QJsonArray


QJsonArray里面封装了Json数组,里面存储多个元素,为了方便操作,所有元素类型统一为QJsonValue类型
注意:QJsonArray内元素是无序的,完全按照添加顺序存储。
先添加,放在前面,后添加放在后面。插入,就放在插入的位置。


2.4.1 创建空的Json数组


QJsonArray::QJsonArray() //得到空的Json数组,通过size()方法,返回值为0


2.4.2 添加数据


2.4.3 计算数组内元素的个数


int QJsonArray::count() const; 
int QJsonArray::size() const;


2.4.4 从数组中取出某一个元素的值


2.4.5 从数组中删除某一个元素的值


2.4.6 遍历


1、使用迭代器遍历(和使用迭代器遍历STL容器一样) 
2、使用数组方式遍历


总结:通过[]或者takeAt方法得到返回值为QJsonValue类型,通过返回数据QJsonValue类型进行判断,然后调用“to”方法得到原始数据。取出的原始元素,不是我们需要的数据类型,需要"to方法"进行换行。

2.6.7 QJsonObject和QJsonArray的区别


QJsonObject是用于表示JSON对象的类,它类似于C++中的std::map或字典数据结构,可以使用键值对存储和访问数据。每个键都是唯一的,与每个值关联。QJsonObject内部以键值对的形式组织数据,其中键是字符串,值可以是字符串、数字、布尔值、其他JSON对象或JSON数组。

QJsonArray是用于表示JSON数组的类,它类似于C++中的std::vector或列表数据结构,可以按照索引顺序存储和访问数据。QJsonArray可以包含多个元素,每个元素可以是字符串、数字、布尔值、其他JSON对象或JSON数组。

区别总结如下:

  • QJsonObject用于表示JSON对象,通过键值对存储和访问数据。
  • QJsonArray用于表示JSON数组,按照索引顺序存储和访问数据。


在处理复杂的JSON数据时,QJsonObject和QJsonArray经常会一起使用。例如,一个JSON对象的值可以是一个JSON数组,而一个JSON数组的元素也可以是JSON对象。这样的结构可以通过嵌套使用QJsonObject和QJsonArray来表示。

请注意,在使用QJsonObject和QJsonArray之前,你需要包含相应的头文件#include <QJsonObject>和#include <QJsonArray>,并链接到QtCore模块。

2.5 QJSonDocument


它封住了一个完整的Json文档,并且可以从UTF-8编码的基于文本的表示以及Qt自己的二进制格式读取和写入该文档。 QJsonObject和QJsonArray这两个对象中的数据是不能直接转换为字符串类型的, 如果要进行数据传输或者数据的持久化,操作的都是字符串类型,不是QJsonArray或者QjsonObject类型, 需要使用JsonDocument进行二者之间的转换。 

2.5.1 QJsonArray和QJsonObject->字符串

  • QJsonDocument(const QJsonDocument &other):移动构造 右值引用 不可取地址的数据
  • QJsonDocument(QJsonDocument &&other):拷贝构造 左值引用  可取地址数组
  • void setArray(const QJsonArray &array):设置空QJsonDocument对象
  • void setObject(const QJsonObject &object):设置空QJsonDocument对象
  • void swap(QJsonDocument &other):交换两个QJsonDocument对象


将QJsonDocument对象转换为字符串QByteArray
QByteArray toJson(QJsonDocument::JsonFormat format) const

  • 创建一个QJsonObject,并添加了一些键值对。
  • 我们使用toJson将QJsonObject转换为QByteArray
  • 我们将QByteArray转换为std::string,并打印出来。
  1. #include <QJsonDocument>
  2. #include <QJsonObject>
  3. #include <QDebug>
  4. QJsonObject jsonObject;
  5. jsonObject["key1"] = "value1";
  6. jsonObject["key2"] = 42;
  7. QJsonDocument jsonDocument(jsonObject);
  8. QByteArray byteArray = jsonDocument.toJson();
  9. std::string jsonString = byteArray.toStdString();
  10. qDebug() << "JSON String:" << jsonString.c_str();

也可以将QByteArray转换为QString,而不是std::string。例如,可以使用QString::fromUtf8()函数将字节数组转换为QString。

请注意,在使用QJsonDocument之前,你需要包含了#include <QJsonDocument>头文件,并链接到QtCore模块。

2.5.2 字符串->QJsonArray和QJsonObject 

将字符串QByteArray 转换为QJsonDocument 对象

QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = nullptr)//第一个参数传入字符串,返回QJsonDocument 对象

  • 创建一个包含JSON数据格式的字符串jsonString
  • 将字符串转换为QByteArray
  • fromJson()将函数解析为QJsonDocument对象
  • isObject()判断是否为有效JSON对象,是则转换为QJsonObject对象
  • 通过键来获取QJsonObject中的值。
  1. #include <QJsonDocument>
  2. #include <QJsonObject>
  3. #include <QDebug>
  4. QString jsonString = "{\"key1\":\"value1\", \"key2\":42}";
  5. QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8());
  6. if (!jsonDocument.isNull()) {
  7. if (jsonDocument.isObject()) {
  8. QJsonObject jsonObject = jsonDocument.object();
  9. QString value1 = jsonObject["key1"].toString();
  10. int value2 = jsonObject["key2"].toInt();
  11. qDebug() << "key1:" << value1;
  12. qDebug() << "key2:" << value2;
  13. }
  14. }

3 Json文件操作的例子

3.1 主要运用技术方法

  • Json文件的序列化反序列化
  • QFile文件操作
  • QJsonDocument、QJsonArray、QJsonObject、QJsonArray

 Json数据内容

数据有三层嵌套,对象"{}"套对象"{}",对象"{}"套数组"[]"

  1. //test.json
  2. //Json描述一个人的信息:
  3. {
  4. "NAME":"ACE",
  5. "Sex":"man",
  6. "Age":20,
  7. "Family":{
  8. "Father":"Babi",
  9. "Mother":"MaMi",
  10. "brother":["aa","bb","cc"]
  11. },
  12. "IsLive":"true",
  13. "Comment":'yyds'
  14. }

3.2  Json文件序列化:writeJson函数代码实现


3.2.1 序列化


序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。对象的状态(包括属性、数据)被转换为字节流或其他表示形式,以便可以在不同的环境中传输、存储或重建对象。序列化可以将对象转换为平台无关的格式,使得可以在不同的编程语言和平台之间进行对象的交互和传输。


此处的序列化指:将QJsonObject  通过QJsonDocument转换为  QByteArray(即文本格式字符串)  QJSonObject/QJsonArray===>字符串

序列化的主要目的有以下几点:
                持久化对象:将对象保存到文件系统或数据库中,以便在以后重新加载和使用。

                对象传输:将对象通过网络传输给其他系统或进程。

                远程过程调用(RPC):通过将对象序列化为消息,实现跨网络调用远程方法。

                对象复制:通过将对象序列化为字节流,实现对象的复制和克隆。

在序列化过程中,对象的状态通常包括其属性值、字段值和关联的对象等信息。


一些常见的序列化格式包括JSON(JavaScript Object Notation)、XML(eXtensible Markup Language)、Protocol Buffers等。


3.2.2 QJsonArray或者QJsonObject===>字符串


创建QJsonDocument对象
QJsonDocument::QJsonDocument(const QJsonObject &object);
QJsonDocument::QJsonDocument(const QJsonArray &array);
通过构造函数将示例化后的QJsonObject 或者 QJsonArray转换为QJsonDocument对象 

将文件对象中的数据进行序列化
QByteArray QJsonDocument::toJson(QJsonDocument::JsonFormat format) const//文本格式
QByteArray  QJsonDocument::toBinaryData() const//二进制格式
通过调用toXXX()方法可以将QJsonDocument对象转换为文本格式或者二进制格式的Json字符串 

使用得到的字符串进行数据传输或者磁盘文件存储

writeJson函数: 

  1. void MainWindow::writeJson()
  2. {
  3. //Json对象数据组织
  4. QJsonObject obj;
  5. obj.insert("name","ACE");
  6. obj.insert("sex","man");
  7. obj.insert("age",20);
  8. QJsonObject subObj;
  9. obj.insert("father","Babi");
  10. obj.insert("mother","Mami");
  11. QJsonArray array;
  12. array.append("aa");
  13. array.append("bb");
  14. array.append("cc");
  15. obj.insert("brother",array);
  16. obj.insert("family",subObj);
  17. obj.insert("islive","true");
  18. obj.insert("comment","yyds");//Json数据组织
  19. QJsonDocument doc(obj);//第一步 建立QJsonDocument对象
  20. QByteArray json = doc.toJson();//第二步 QJsonDocument对象的数据转文本格式json字符串
  21. QFile file("./test.json");//第三步 字符串存储到计算机磁盘
  22. if(file.open(QFile::WriteOnly))
  23. {
  24. file.write(json);
  25. }
  26. file.close();
  27. }

  • 运行后test.json结果:因为按照键值排序,键值为英文字母所以  排序是英文字母ASCII码的排序。因此和输入程序的顺序明显不同!使用QJsonObject会导致和程序输入顺序不同!!!

3.3 Json文件反序列化:readJson函数实现


3.3.1 反序列

  • 反序列化(Deserialization)是将序列化后的数据转换回原始对象的状态的过程。
  • 在计算机科学和软件开发中,反序列化用于从序列化的表示形式中恢复对象的状态,以便能够使用、操作和处理对象的数据。
  • 在反序列化过程中,序列化的数据(如字节流、JSON字符串、XML文档等)被解析和转换为对象的状态,包括属性、字段和关联的对象等信息,可以将数据重新还原为原始的对象形式,以便进一步使用和操作。
  • 具体的反序列化过程取决于所使用的序列化格式和编程语言。常见的序列化格式如JSON、XML和Protocol Buffers都有相应的反序列化机制。

3.3.2 字符串===>QJsonArray或者 QJsonObject


将得到的Json格式字符串通过QJsonDocument类的静态函数转换为QJsonDocument类对象

  1. [static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = nullptr)//参数为文件格式的字符串
  2. [static] QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, QJsonDocument::DataValidation validation = Validate)//参数为二进制格式


将文本对象转换为json数组/对象


通过调用QJsonQrray或者QJsonObject类提供的API读取存储在对象中的数据 


readJson函数实现

  1. void MainWindow::readJson()
  2. {
  3. QFile file("./test.json");
  4. if(file.open(QFile::ReadOnly))
  5. {
  6. QByteArray all = file.readAll();
  7. QJsonDocument doc = QJsonDocument::fromJson(all);
  8. if(doc.isObject())
  9. {
  10. QJsonObject obj = doc.object();
  11. QStringList keys = obj.keys();
  12. for(int i=0;i<keys.size();++i)
  13. {
  14. QString key =keys.at(i);
  15. QJsonValue value = obj.value(key);
  16. if(value.isBool())
  17. {
  18. qDebug()<<key<<":"<<value.toBool();
  19. }
  20. else if(value.isString())
  21. {
  22. qDebug()<<key<<":"<<value.toString();
  23. }
  24. else if(value.isDouble())
  25. {
  26. qDebug()<<key<<":"<<value.toInt();
  27. }
  28. else if(value.isObject())
  29. {
  30. qDebug()<<key<<":";
  31. QJsonObject subObj = value.toObject();
  32. QStringList subKeys = subObj.keys();
  33. for(int k=0;k<subKeys.size();++k)
  34. {
  35. QJsonValue subValue = subObj.value(subKeys.at(k));
  36. if(subValue.isString())
  37. {
  38. qDebug()<<" "<<subKeys.at(k)<<":"<<subValue.toString();
  39. }
  40. else if(subValue.isArray())
  41. {
  42. qDebug()<<" "<<subKeys.at(k)<<":";
  43. QJsonArray array = subValue.toArray();
  44. for(int m=0;m<array.size();++m)
  45. {
  46. qDebug()<<" "<<array[m].toString();
  47. }
  48. }
  49. }
  50. }
  51. }
  52. }
  53. }
  54. file.close();
  55. }

3.4 整体代码

3.4.1 mainwindow.h
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. QT_BEGIN_NAMESPACE
  5. namespace Ui { class MainWindow; }
  6. QT_END_NAMESPACE
  7. class MainWindow : public QMainWindow
  8. {
  9. Q_OBJECT
  10. public:
  11. MainWindow(QWidget *parent = nullptr);
  12. ~MainWindow();
  13. void writeJson();
  14. void readJson();
  15. private:
  16. Ui::MainWindow *ui;
  17. };
  18. #endif // MAINWINDOW_H

3.4.2 mainwindow.cpp

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include<QJsonDocument>
  4. #include<QJsonObject>
  5. #include<QJsonArray>
  6. #include<QJsonValue>
  7. #include<QDebug>
  8. #include<QFile>
  9. MainWindow::MainWindow(QWidget *parent)
  10. : QMainWindow(parent)
  11. , ui(new Ui::MainWindow)
  12. {
  13. ui->setupUi(this);
  14. QJsonDocument doc;
  15. if(doc.isEmpty())
  16. {
  17. qDebug()<<"Json document is empty...";
  18. }
  19. if(doc.isNull())
  20. {
  21. qDebug()<<"Json document is null...";
  22. }
  23. writeJson();
  24. readJson();
  25. }
  26. MainWindow::~MainWindow()
  27. {
  28. delete ui;
  29. }
  30. /*
  31. //test.json
  32. //Json描述一个人的信息:
  33. {
  34. "NAME":"ACE",
  35. "Sex":"man",
  36. "Age":20,
  37. "Family":{
  38. "Father":"Babi",
  39. "Mother":"MaMi",
  40. "brother":["aa","bb","cc"]
  41. },
  42. "IsLive":"true",
  43. "Comment":'yyds'
  44. }
  45. */
  46. void MainWindow::writeJson()
  47. {
  48. //Json对象数据组织
  49. QJsonObject obj;
  50. obj.insert("name","ACE");
  51. obj.insert("sex","man");
  52. obj.insert("age",20);
  53. QJsonObject subObj;
  54. subObj.insert("father","Babi");
  55. subObj.insert("mother","Mami");
  56. QJsonArray array;
  57. array.append("aa");
  58. array.append("bb");
  59. array.append("cc");
  60. subObj.insert("brother",array);
  61. obj.insert("family",subObj);
  62. obj.insert("islive","true");
  63. obj.insert("comment","yyds");//Json数据组织
  64. QJsonDocument doc(obj);
  65. QByteArray json = doc.toJson();//json数据转文本格式字符串
  66. QFile file("./test.json");
  67. if(file.open(QFile::WriteOnly))
  68. {
  69. file.write(json);
  70. }
  71. file.close();
  72. }
  73. void MainWindow::readJson()
  74. {
  75. QFile file("./test.json");
  76. if(file.open(QFile::ReadOnly))
  77. {
  78. QByteArray all = file.readAll();
  79. QJsonDocument doc = QJsonDocument::fromJson(all);
  80. if(doc.isObject())
  81. {
  82. QJsonObject obj = doc.object();
  83. QStringList keys = obj.keys();
  84. for(int i=0;i<keys.size();++i)
  85. {
  86. QString key =keys.at(i);
  87. QJsonValue value = obj.value(key);
  88. if(value.isBool())
  89. {
  90. qDebug()<<key<<":"<<value.toBool();
  91. }
  92. else if(value.isString())
  93. {
  94. qDebug()<<key<<":"<<value.toString();
  95. }
  96. else if(value.isDouble())
  97. {
  98. qDebug()<<key<<":"<<value.toInt();
  99. }
  100. else if(value.isObject())
  101. {
  102. qDebug()<<key<<":";
  103. QJsonObject subObj = value.toObject();
  104. QStringList subKeys = subObj.keys();
  105. for(int k=0;k<subKeys.size();++k)
  106. {
  107. QJsonValue subValue = subObj.value(subKeys.at(k));
  108. if(subValue.isString())
  109. {
  110. qDebug()<<" "<<subKeys.at(k)<<":"<<subValue.toString();
  111. }
  112. else if(subValue.isArray())
  113. {
  114. qDebug()<<" "<<subKeys.at(k)<<":";
  115. QJsonArray array = subValue.toArray();
  116. for(int m=0;m<array.size();++m)
  117. {
  118. qDebug()<<" "<<array[m].toString();
  119. }
  120. }
  121. }
  122. }
  123. }
  124. }
  125. }
  126. file.close();
  127. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/1016470
推荐阅读
相关标签
  

闽ICP备14008679号