前言:
- 最近我遇到了一個需要讀取本地文件生成json文件的問題,在這里分享下如何在qt中寫一個生成json的程序
- 當然也可以使用一些可視化的工具來寫json文件(比如:notepad–,還有一些ide都可以),但未免太過于麻煩
- 本文會以一個以qmake搭建的qt項目為例,讀取項目中資源的文件,將文件分類生成一個json文件,并選擇json文件生成的目錄處
首先介紹下會用到的類
一.QDir類(Qt框架中用于處理目錄和路徑的類)
- QDir的構造函數可以接收路徑參數(QString類型),QDir對象指向該路徑
QDir(const QString &path = QString())
- 例如像這樣使用:
QString resoucePath=":/music/";//像這種加了:的相對路徑是已經放入項目中資源部分的文件路徑
QDir dir(resoucePath);
- 可以使用
entryList()
方法輸出QDir對象指向目錄中內容,也就是文件名和子目錄,這個也就是我們要寫入json文件的數據,讀取文件路徑存入生成的json里
QStringList QDir::entryList(const QStringList &nameFilters, QDir::Filters filters = NoFilter, QDir::SortFlags sort = NoSort) constQStringList QDir::entryList(QDir::Filters filters = NoFilter, QDir::SortFlags sort = NoSort) const
//entryList方法可以不需要寫參數,可以看到可以有個重載不需要nameFilters參數,另兩個參數都初始化了
-
entryList
方法返回一個QStringList類型,有三個參數,這三個參數分別為:
名稱過濾器(nameFilters):根據文件名篩選條目
過濾器(Filters):控制列處哪些類型的條目,也就是文件類型
排序標志(SortFlags):控制條目列表的排序方式 -
過濾器是一個
QDir::Filters
類型的枚舉值,可以通過位運算組合多個過濾器使用,常用過濾器:
QDir::Dirs
:只列出目錄
QDir::Files
:只列出文件
QDir::NoDotAndDotDot
:不列出.(當前目錄)和…(上級目錄)
QDir::Hidden
:列出隱藏文件
QDir::NoSymLinks
:不列處符號鏈接(符號鏈接就是我們看見的文件的快捷方式)
QDir::Readable
:只列出可讀的文件或目錄
QDir::Writable
: 只列出可寫的文件或目錄
QDir::Executable
:只列出可執行的文件或目錄
QDir::System
:列出系統文件 -
排序標志是一個QDir::SortFlags類型的枚舉值,可以通過位運算組合多個排序標志,常見排序標志:
QDir::Name
:按名稱排序(也就是按文件名稱字母排序)
QDir::Time
:按修改時間排序
QDir::Size
:按文件大小排序
QDir::Type
:按文件類型排序
QDir::Unsorted
:不排序,按文件系統順序返回
QDir::IgnoreCase
:忽略大小寫排序
QDir::DirsFirst
:目錄優于文件
QDir::DirsLast
:目錄排在文件之后
QDir::Reversed
:反向排序
qDebug()<<dir.entryList();//輸出一遍看下
QStringList filters;//名稱過濾器
filters<<"*.mp3";//只獲取后綴名為MP3的文件
QStringList files=dir.entryList(filters,QDir::Files);//過濾器只列出文件,排序標志為初始的不排序
輸出示例如下:
- 還可以對目錄進行管理,例如使用
mkdir()
、rename()
和rmdir()
等方法創建、重命名或刪除目錄。這些功能以及其他功能就不演示了,畢竟本文沒有用上
二.QJsonObject類
-
QJsonObject
類似于map
,以鍵值對的形式存儲數據,其中鍵是字符串,值可以是QJsonValue
類型(包括字符串,數字,布爾值,數組,對象等)。 -
常用方法:
1.插入數據:
insert(const QString &key,const QJsonValue &value)
:插入一個鍵值對
2.獲取數據:
value(const QString &key) const
:根據鍵獲取值
operator[](const QString &key)
:通過鍵訪問值
3.檢查鍵是否存在:
contains(const QString &key) const
:檢查是否包含某個值
4.刪除數據:
remove(const QString &key)
:刪除指定鍵的鍵值對
5.轉換為JSON字符串:
使用QJsonDocument
將QJsonObject
轉換為JSON字符串
6.從JSON字符串解析:
使用QJsonDocument
將JSON字符串解析為QJsonObject
-
示例:
QJsonObject root;//QJsonObject的的值可以是數組,這個示例存儲的值是Json數組QJsonArray manList;QJsonArray womanList;QJsonArray bgmList;QJsonArray endingList;QJsonArray otherList;for(QString& file:files){QString filePath=resoucePath+file;if(file.startsWith("Man_")){//startsWith是用于檢查字符串是否以指定的前綴開頭manList.append(filePath);}else if(file.startsWith("Woman_")){womanList.append(filePath);}else if(file.startsWith("MusicEx_")){if(file.contains("Win")||file.contains("Lose")){endingList.append(filePath);}else{bgmList.append(filePath);}}else{otherList.append(filePath);}}root["Man"]=manList;//用不同的鍵分類存入root["Woman"]=womanList;root["BGM"]=bgmList;root["Ending"]=endingList;root["Other"]=otherList;
三.QJsonDocument類
-
可以將QJsonObject和QJsonArray轉換為Json文檔
-
常用方法:
1.從Json字符串解析:
static QJsonDocument fromJson(const QByteArray &json)
:從Json字符串解析為QJsonDocument
2.從Json二進制數據解析:
static QJsonDocument fromBinaryData(const QByteArray &data)
:從二進制數據解析為QJsonDocument
3.轉換為Json字符串:
QByteArray toJson(QJsonDocument::JsonFormat format=Indented)
:將QJsonDocument
轉換為Json
字符串
這個方法對于生成的Json字符串格式有著一個枚舉類型的參數:
enum JsonFormat{Indented,Compact}
:Indented
是格式化的Json字符串(帶縮進),Compact
是緊湊的Json字符串
4.轉換為二進制數據:
QByteArray toBinaryData()
:將QJsonDocument
轉換為二進制數據
5.獲取Json數據:
QJsonObject object() const
:如果文檔里包含QJsonObejct
,則返回該對象
QJsonArray array() const
:如果文檔里包含QJsonArray
,則返回該數據
6.檢查文檔類型:
bool isObject() const
:檢查文檔是否包含QJsonObject
bool isArray() const
:檢查文檔里是否包含QJsonArray
7.檢查文檔是否為空:
bool isEmpty() const
:檢查文檔是否為空
四.QFile類(對文件的操作)
- 打開文件:
bool open(QIODevice::OpenMode mode)
:以指定模式打開文件
常用模式:
QIODevice::ReadOnly
:只讀模式
QIODevice:WriteOnly
:只寫模式
QIODevice::ReadWrite
:讀寫模式
QIODevice::Append
:追加模式
QIODevice::Truncate
:清空文件內容 - 關閉文件
void close()
:關閉文件 - 讀取文件
QByteArray readAll()
:讀取文件所有內容
QByteArray read(qint64 maxSize)
:讀取指定大小的內容
QString readLine()
:讀取一行內容 - 寫入文件
qint64 write(const QByteArray &data)
:寫入數據
qint64 write(const char* data,qint64 len)
:寫入指定長度的數據 - 文件管理
bool copy(const QString &newName)
:復制文件
bool rename(const QString &newName)
:重命名文件
bool remove()
:刪除文件 - 文件信息:
qint64 size()
:獲取文件大小
bool exists()
:檢查文件是否存在 - 錯誤處理:
QFile::FileError error()
:獲取錯誤碼
QString errorString()
:獲取錯誤信息
關于最終Json文件的生成的目錄
-
首先要知道在使用
QFile
類對象創建文件對象時,如果沒有指定文件的完整路徑,那么該文件會被創建在當前項目工作目錄,比如這樣創建時:
QFile jsonFile("PlayList.json");
,當前工作目錄可以用QDir::currentPath()
獲取,返回類型是QString
,
打印:qDebug()<<QDir::currentPath()
-
如果想獲取當前應用程序的可執行文件所在的目錄的路徑,可以使用
QCoreApplication::applicationDirPath()
,返回類型為QString
-
如果你想將文件生成在根目錄也就是與.pro同級目錄,
在.pro文件添加以下兩句:
//定義PRO_DIR為當前.pro文件所在的目錄
PRO_DIR = $$PWD
//將PRO_DIR作為宏定義傳遞給C++代碼,\\\"是為了確保PRO_DIR的值
DEFINES += PRO_DIR=\\\"$$PRO_DIR\\\"
完整實例生成Json文件代碼:
- 這個例子是寫一個類來實現將Json文件生成在項目根目錄的,讀取項目中資源的文件:
頭文件:
#ifndef BGMLIST_H
#define BGMLIST_H#include <QObject>class BGMList : public QObject
{Q_OBJECT
public:explicit BGMList(QObject *parent = nullptr);QString getProjectRootPath();//該函數返回Json生成的目錄
signals:
private:
};#endif // BGMLIST_H
#include "bgmlist.h"
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>BGMList::BGMList(QObject *parent): QObject{parent}
{QString resoucePath=":/music/";//像這種加了:的相對路徑是已經放入項目中資源部分的文件路徑QDir dir(resoucePath);//qDebug()<<dir.entryList();if(!dir.exists()){qDebug()<<"資源路徑不存在";return;}qDebug()<<resoucePath;QStringList filters;//名稱過濾器filters<<"*.mp3";//只獲取后綴名為MP3的文件QStringList files=dir.entryList(filters,QDir::Files);//過濾器只列出文件,排序標志為初始的不排序QJsonObject root;QJsonArray manList;QJsonArray womanList;QJsonArray bgmList;QJsonArray endingList;QJsonArray otherList;for(QString& file:files){QString filePath=resoucePath+file;if(file.startsWith("Man_")){//startsWith是用于檢查字符串是否以指定的前綴開頭manList.append(filePath);}else if(file.startsWith("Woman_")){womanList.append(filePath);}else if(file.startsWith("MusicEx_")){if(file.contains("Win")||file.contains("Lose")){endingList.append(filePath);}else{bgmList.append(filePath);}}else{otherList.append(filePath);}}root["Man"]=manList;root["Woman"]=womanList;root["BGM"]=bgmList;root["Ending"]=endingList;root["Other"]=otherList;QJsonDocument doc(root);QString projectRootPath=getProjectRootPath()+"/PlayList.json";//Json文件的目錄QFile jsonFile("PlayList.json");//qDebug()<<QDir::currentPath();if(jsonFile.open(QIODevice::WriteOnly)){//只寫模式jsonFile.write(doc.toJson());jsonFile.close();qDebug()<<"PlayList.json已生成";}else{qDebug()<<"未生成";}
}QString BGMList::getProjectRootPath()
{QString appDir=QCoreApplication::applicationDirPath();//qDebug()<<appDir;QDir dir(appDir);dir.cdUp();//qDebug()<<PRO_DIR;//$$PWD就是.pro文件的目錄級別return PRO_DIR;}
- Json文件截圖展示: