QT中json读写

转自:     

 

一、写入:

简介

介绍使用Qt读写JSON文件。如果你对JSON不是很了解,请阅读我之前的一篇文章json简介
使用的开发环境为:

Qt 5.12.0+Deepin 15.8

在Qt中与JSON相关的类有以下几个,Q=QJsonDocument,QJsonArray,QJsonObject,QJsonParseError,QJsonValue。

 

 

 

json

其中QJsonDocument类提供了读写JSON文档的方式,我们可以通过该类的方法QJsonDocument::fromJson()将一个JSON文档转换成QJsonDocument类,或者通过QJsonDocument::toJson()和QJsonDocument::toBinaryData()函数将一个QJsonDocument类转换为QByteArray,这样我们就可以很轻松地将其写入文件。

QJsonArray封装了JSON中的数组。
QJsonObject封装了JSON中的对象。
QJsonValue封装了JSON中的值。
QJsonParseError 用于报告JSON解析中的错误类型。

使用QJsonObject简单演示

首先,我们使用Qt creator创建一个Qt Console Application项目,项目名称位置可随意。

 

 

 

creator

修改main.cpp中的代码如下所示

 1 #include <QJsonArray>
 2 #include <QJsonDocument>
 3 #include <QJsonObject>
 4 #include <QJsonParseError>
 5 #include <QJsonValue>
 6 #include <QString>
 7 #include <QDebug>
 8 #include <QFile>
 9 #include <QDateTime>
10 #include <QDir>
11 
12 int main(int argc, char *argv[]) {
13 // 以读写方式打开主目录下的1.json文件,若该文件不存在则会自动创建
14     QFile file(QDir::homePath() + "/1.json");
15     if(!file.open(QIODevice::ReadWrite)) {
16         qDebug() << "File open error";
17     } else {
18         qDebug() <<"File open!";
19     }
20 // 使用QJsonObject对象插入键值对。
21     QJsonObject jsonObject;
22     jsonObject.insert("name", "tom");
23     jsonObject.insert("age", "18");
24     jsonObject.insert("time", QDateTime::currentDateTime().toString());
25 
26 // 使用QJsonDocument设置该json对象
27     QJsonDocument jsonDoc;
28     jsonDoc.setObject(jsonObject);
29 
30 // 将json以文本形式写入文件并关闭文件。
31     file.write(jsonDoc.toJson());
32     file.close();
33 
34     qDebug() << "Write to file";
35     return 0;
36 }
View Code

 

之后打开你的终端(linux环境下), 会看到我们的程序在主目录下生成了一个1.json的文件。然后查看下里面的内容。

 

 

 

json file

不知道你有没有注意到,我们在jsonObject中插入键值对的顺序和文件中的键值对顺序不太一样,这是因为JSON中的object本身是指无序的键值对,它不能确保我们插入的顺序和实际保存的数据顺序一致。如果你的数据需要顺序一致,考虑JSON中的array,array是值的有序列表。

 

 

 

code

简单使用QJsonArray

修改main.cpp中的代码如下,注:该代码会清空主目录先1.json的原有内容,如果你想保留原有的文件内容,请备份或者修改写入的文件名。

 1 #include <QJsonArray>
 2 #include <QJsonDocument>
 3 #include <QJsonObject>
 4 #include <QJsonParseError>
 5 #include <QJsonValue>
 6 #include <QString>
 7 #include <QDebug>
 8 #include <QFile>
 9 #include <QDateTime>
10 #include <QDir>
11 
12 int main(int argc, char *argv[]) {
13     // 以读写方式打开主目录下的1.json文件,若该文件不存在则会自动创建
14     QFile file(QDir::homePath() + "/1.json");
15     if(!file.open(QIODevice::ReadWrite)) {
16         qDebug() << "File open error";
17     } else {
18         qDebug() <<"File open!";
19     }
20 
21     // 清空文件中的原有内容
22     file.resize(0);
23 
24     // 使用QJsonArray添加值,并写入文件
25     QJsonArray jsonArray;
26     jsonArray.append("name");
27     jsonArray.append(18);
28     jsonArray.append(QDateTime::currentDateTime().toString());
29 
30     QJsonDocument jsonDoc;
31     jsonDoc.setArray(jsonArray);
32 
33     file.write(jsonDoc.toJson());
34     file.close();
35 
36     qDebug() << "Write to file";
37     return 0;
38 }
View Code

 

这次文件中的数据顺序,和我们扩展JSON数组中的顺序是一致的。


 

 

 

jsonArray

稍微复杂的例子

我们注意到JSON中的值可以是字符串、数组、对象、数字等,因此我们试试结合使用一下。

 1 #include <QJsonArray>
 2 #include <QJsonDocument>
 3 #include <QJsonObject>
 4 #include <QJsonParseError>
 5 #include <QJsonValue>
 6 #include <QString>
 7 #include <QDebug>
 8 #include <QFile>
 9 #include <QDateTime>
10 #include <QDir>
11 #include <QThread>
12 
13 int main(int argc, char *argv[]) {
14     // 以读写方式打开主目录下的1.json文件,若该文件不存在则会自动创建
15     QFile file(QDir::homePath() + "/1.json");
16     if(!file.open(QIODevice::ReadWrite)) {
17         qDebug() << "File open error";
18     } else {
19         qDebug() <<"File open!";
20     }
21 
22     // 清空文件中的原有内容
23     file.resize(0);
24 
25     // 使用QJsonArray添加值,并写入文件
26     QJsonArray jsonArray;
27 
28     for(int i = 0; i < 3; i++) {
29         QJsonObject jsonObject;
30         jsonObject.insert("name", QString::number(i+1));
31         jsonObject.insert("age", i+18);
32         jsonObject.insert("time", QDateTime::currentDateTime().toString());
33         jsonArray.append(jsonObject);
34         QThread::sleep(2);
35     }
36 
37     QJsonObject jsonObject;
38     jsonObject.insert("number", jsonArray.size());
39     jsonArray.append(jsonObject);
40 
41     QJsonDocument jsonDoc;
42     jsonDoc.setArray(jsonArray);
43 
44     file.write(jsonDoc.toJson());
45     file.close();
46 
47     qDebug() << "Write to file";
48     return 0;
49 }
View Code

 

结果如下所示


 

 

 

 

二、解析:

之前介绍了简单的示例,这次我们进行JSON文件的解析。
在你的桌面新建文件命名为test.json,内容填写如下:

 1 {
 2     "postsNum" : 2,
 3     "posts" : [
 4         {
 5             "postID" : 10086,
 6             "postTitle" : "hello",
 7             "postContent" : "你好啊"
 8         },
 9         {
10             "postID" : 10010,
11             "postTitle" : "hi",
12             "postContent" : "大家好"
13         }
14     ]
15 }

 

从JSON定义来看,这是一个包含有两个键值对的对象,其中一个对象的名字是"postsNum",值是一个数字,另一键值对的名字是"posts",值是一个数组。这个数组由两个对象组成,每个对象由三个相同的键值对组成,第一个键值对名字为"postID" ,值为数字;第二个键值对名字为 "postTitle" ,值为字符串 "hello";第三个键值对名字为 "postContent" ,值为字符串。实际上,数组中的对象描述了一个简单的帖子的数据结构,这个帖子有postID、postTitle、postContent组成。

接下来我们使用Qt Creator新建一个Qt Console Application项目,名称和位置可以随意。

修改默认生成的main.cpp中的代码如下所示:

 1 #include <QDir>
 2 #include <QFile>
 3 #include <QJsonArray>
 4 #include <QJsonDocument>
 5 #include <QJsonObject>
 6 #include <QJsonParseError>
 7 #include <QJsonValue>
 8 
 9 #include <QSysInfo>
10 
11 #include <cstdlib>
12 #include <iostream>
13 
14 using std::cout;
15 
16 int main( int argc, char *argv[] ) {
17     // Qt的一个宏,消除未使用变量的警告,无实际作用
18     // 定义为,#define Q_UNUSED(x) (void)x
19     Q_UNUSED( argc );
20     Q_UNUSED( argv );
21 
22     // 如果当前操作系统为windows系统的话
23     // 修改控制台的编码为utf8,防止中文乱码
24     if ( QSysInfo::productType() == "windows" ||
25          QSysInfo::productType() == "winrt" ) {
26         system( "chcp 65001" );
27     }
28 
29     cout << "当前使用的操作系统类型为:";
30     cout << QSysInfo::productType().toStdString() << "\n";
31     // 默认打开的文件位置为用户桌面的test.txt文件。
32     QFile file( QDir::homePath() + "/Desktop/test.json" );
33     if ( !file.open( QIODevice::ReadWrite ) ) {
34         cout << "文件打开失败!\n";
35         exit( 1 );
36     }
37     cout << "文件打开成功\n";
38 
39     QJsonParseError jsonParserError;
40     QJsonDocument   jsonDocument =
41         QJsonDocument::fromJson( file.readAll(), &jsonParserError );
42 
43     if ( !jsonDocument.isNull() &&
44          jsonParserError.error == QJsonParseError::NoError ) {
45         cout << "文件解析成功\n";
46         if ( jsonDocument.isObject() ) {
47             QJsonObject jsonObject = jsonDocument.object();
48             if ( jsonObject.contains( "postsNum" ) &&
49                  jsonObject.value( "postsNum" ).isDouble() ) {
50                 cout << "postsNum is " << jsonObject.value( "postsNum" ).toInt()
51                      << "\n";
52             }
53 
54             if ( jsonObject.contains( "posts" ) &&
55                  jsonObject.value( "posts" ).isArray() ) {
56                 QJsonArray jsonArray = jsonObject.value( "posts" ).toArray();
57                 for ( int i = 0; i < jsonArray.size(); i++ ) {
58                     if ( jsonArray[ i ].isObject() ) {
59                         QJsonObject jsonObjectPost = jsonArray[ i ].toObject();
60                         if ( jsonObjectPost.contains( "postID" ) &&
61                              jsonObjectPost.contains( "postTitle" ) &&
62                              jsonObjectPost.contains( "postContent" ) &&
63                              jsonObjectPost.value( "postID" ).isDouble() &&
64                              jsonObjectPost.value( "postTitle" ).isString() &&
65                              jsonObjectPost.value( "postContent" )
66                                  .isString() ) {
67                             cout << "posts[" << i << "] :\n";
68                             cout << "postID is "
69                                  << jsonObjectPost.value( "postID" ).toInt()
70                                  << "\n";
71                             cout << "postTitle is "
72                                  << jsonObjectPost.value( "postTitle" )
73                                         .toString()
74                                         .toStdString()
75                                  << "\n";
76                             cout << "postContent is "
77                                  << jsonObjectPost.value( "postContent" )
78                                         .toString()
79                                         .toStdString()
80                                  << "\n";
81                         }
82                     }
83                 }
84             }
85         }
86     }
87 
88     file.close();
89     cout << "按任意键退出程序\n";
90 
91     return 0;
92 }
View Code

 

这段代码也很容易理解,首先判断当前系统是否为windows,如果是的话就修改CMD编码为utf8,防止出现中文乱码,之后打开桌面上的test.json文件,解析为json文件并输出里面的数据。

posted @ 2020-04-02 18:08  阳光下的小土豆  阅读(1864)  评论(0编辑  收藏  举报