Qt 高效讀寫JSON文件,玩轉QJsonDocument與QJsonObject

一、前言

JSON作為輕量級的數據交換格式,已成為開發者必備技能。Qt框架為JSON處理提供了完整的解決方案,通過QJsonDocumentQJsonObjectQJsonArray三大核心類,輕松實現數據的序列化與反序列化。

JSON vs INI

特性JSONINI
數據結構支持嵌套對象/數組扁平鍵值對
數據類型豐富(含null)僅字符串
適用場景復雜配置/網絡傳輸簡單配置

二、環境準備

2.1 項目配置

.pro文件中添加JSON模塊:

QT += core

2.2 包含頭文件

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>

三、核心API詳解

3.1 QJsonDocument類

方法說明示例
fromJson(jsonData, error)解析JSON數據QJsonParseError err; doc = QJsonDocument::fromJson(data, &err)
toJson(format)序列化為字符串QByteArray json = doc.toJson(QJsonDocument::Indented)
object()獲取根對象QJsonObject root = doc.object()
array()獲取根數組QJsonArray arr = doc.array()
isObject()是否對象類型if(doc.isObject())
isArray()是否數組類型if(doc.isArray())
setObject(obj)設置根對象doc.setObject(newObj)
setArray(arr)設置根數組doc.setArray(newArr)

3.2?QJsonObject類

方法說明示例
insert(key, value)插入鍵值對obj.insert("name", "Alice")
remove(key)刪除指定鍵obj.remove("obsoleteKey")
contains(key)檢查鍵是否存在if(obj.contains("timestamp"))
value(key)安全獲取值QJsonValue val = obj.value("age")
operator[](key)直接訪問值obj["score"] = 95.5
keys()獲取所有鍵列表QStringList keys = obj.keys()
size()獲取鍵值對數量qDebug() << "對象大小:" << obj.size()
isEmpty()判斷是否為空if(obj.isEmpty()) return;

3.3 QJsonArray?類

方法說明示例
append(value)追加元素arr.append(42)
insert(index, value)插入元素arr.insert(0, "First")
removeAt(index)刪除指定位置元素arr.removeAt(3)
replace(index, value)替換元素arr.replace(2, true)
at(index)獲取指定位置值QJsonValue val = arr.at(0)
size()獲取元素數量for(int i=0; i<arr.size(); ++i)
isEmpty()判斷是否為空if(arr.isEmpty()) return;

3.4?QJsonValue類型處理

方法說明
isBool()布爾類型
isDouble()數值類型
isString()字符串類型
isArray()JSON數組
isObject()JSON對象
isNull()空值
isUndefined()未定義值

安全轉換方法:

QJsonValue val = /* ... */;// 帶默認值的轉換
int num = val.toInt(0); // 轉換失敗返回0
QString str = val.toString("default");// 帶錯誤檢測的轉換
bool ok;
double d = val.toDouble(&ok);
if(!ok) qWarning() << "轉換double失敗";// 對象/數組轉換
if(val.isObject()) {QJsonObject obj = val.toObject();
}
else if(val.isArray()) {QJsonArray arr = val.toArray();
}// 特殊類型處理
QJsonValue nullVal = QJsonValue::Null;
QJsonValue undefinedVal; // 默認構造為Undefined

四、讀寫JSON

4.1 寫入JSON文件,創建復雜JSON結構

void writeJsonFile()
{// 創建根對象QJsonObject rootObj;// 基礎數據rootObj["appName"] = "QtConfigManager";rootObj["version"] = "1.2.0";rootObj["debugMode"] = false;// 嵌套對象QJsonObject dbConfig;dbConfig["host"] = "127.0.0.1";dbConfig["port"] = 3306;dbConfig["credentials"] = QJsonArray{"root", "123456"};rootObj["database"] = dbConfig;// 創建數組QJsonArray recentFiles;recentFiles.append("project1.pro");recentFiles.append("mainwindow.cpp");rootObj["recentFiles"] = recentFiles;// 生成JSON文檔QJsonDocument doc(rootObj);// 寫入文件QFile file("config.json");if(file.open(QIODevice::WriteOnly)){file.write(doc.toJson(QJsonDocument::Indented));file.close();qDebug() << "JSON文件寫入成功!";} else {qWarning() << "文件打開失敗:" << file.errorString();}
}

4.2 讀取JSON文件

void readJsonFile()
{QFile file("config.json");if(!file.open(QIODevice::ReadOnly)) {qCritical() << "文件打開失敗:" << file.errorString();return;}// 解析JSONQJsonDocument doc = QJsonDocument::fromJson(file.readAll());if(doc.isNull()){qWarning() << "JSON解析失敗!";return;}// 獲取根對象QJsonObject root = doc.object();// 讀取基礎配置QString appName = root["appName"].toString();bool debugMode = root["debugMode"].toBool();// 解析嵌套對象QJsonObject dbConfig = root["database"].toObject();QString host = dbConfig["host"].toString();QJsonArray credentials = dbConfig["credentials"].toArray();// 遍歷數組QJsonArray files = root["recentFiles"].toArray();qDebug() << "最近文件列表:";for(const QJsonValue &val : files){qDebug() << "->" << val.toString();}// 安全取值示例int port = dbConfig.value("port").toInt(3306); // 默認值
}

五、實戰技巧:處理復雜場景

5.1 動態鍵名處理

QJsonObject config;
QString dynamicKey = "custom_" + QString::number(QDateTime::currentSecsSinceEpoch());
config[dynamicKey] = "特殊配置項";

5.2 日期時間處理

// 寫入
QJsonObject obj;
obj["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);// 讀取
QDateTime dt = QDateTime::fromString(obj["timestamp"].toString(), Qt::ISODate);

5.3 二進制數據編碼

// Base64編碼存儲
QByteArray imageData = /*...*/;
obj["avatar"] = QString(imageData.toBase64());// 解碼讀取
QByteArray restoredData = QByteArray::fromBase64(obj["avatar"].toString().toUtf8());

六、錯誤處理與調試

6.1 錯誤檢測

QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(rawData, &parseError);if(parseError.error != QJsonParseError::NoError){qDebug() << "JSON解析錯誤:" << parseError.errorString()<< "at offset" << parseError.offset;
}

6.2 調試輸出

// 格式化輸出JSON
qDebug().noquote() << doc.toJson(QJsonDocument::Indented);

七、性能優化建議

  1. 大文件處理

    • 使用流式解析(QJsonDocument不適合GB級文件)

    • 考慮第三方庫(如RapidJSON)處理超大JSON

  2. 內存管理

    // 及時釋放不再使用的JSON對象
    {QJsonObject tempObj;// 操作臨時對象
    } // 自動釋放內存
  3. 緩存機制

    • 對頻繁讀取的配置進行內存緩存

    • 使用QCache實現LRU緩存

八、擴展應用:與QVariant互轉

8.1 對象轉換

// JSON轉QVariantMap
QVariantMap vmap = doc.object().toVariantMap();// QVariantMap轉JSON
QJsonObject::fromVariantMap(vmap);

8.2 序列化對象

class UserSettings {
public:void saveToJson(QJsonObject &json) const {json["theme"] = m_theme;json["fontSize"] = m_fontSize;}void loadFromJson(const QJsonObject &json) {m_theme = json["theme"].toString();m_fontSize = json.value("fontSize").toInt(12);}
};

九、實踐總結

  1. 文件操作規范

    • 使用QSaveFile實現原子寫入

    • 設置文件權限:QFileDevice::ReadOwner | QFileDevice::WriteOwner

  2. 版本兼容性

    {"metadata": {"schemaVersion": "1.1","createdAt": "2023-08-20"}
    }
  3. 安全建議

    • 校驗JSON數據完整性

    • 限制最大文件尺寸

    • 敏感數據加密存儲

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73257.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73257.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73257.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Kubernetes(k8s)-Pod親和性(Affinity)和反親和性(Anti-affinity)

作者介紹&#xff1a;簡歷上沒有一個精通的運維工程師。請點擊上方的藍色《運維小路》關注我&#xff0c;下面的思維導圖也是預計更新的內容和當前進度(不定時更新)。 我們上一章介紹了Docker基本情況&#xff0c;目前在規模較大的容器集群基本都是Kubernetes&#xff0c;但是K…

ESP32-C3物聯網方案,智能設備創新升級,無線交互控制通信應用

在物聯網技術迅猛發展的今天&#xff0c;各類智能設備如雨后春筍般涌現&#xff0c;深度融入我們生活與工作的各個角落&#xff0c;物聯網正以一種前所未有的速度改變著我們的世界。 想象一下&#xff0c;清晨&#xff0c;當第一縷陽光灑進房間&#xff0c;智能窗簾自動緩緩拉…

Python自動化測試 之 DrissionPage 的下載、安裝、基本使用詳解

Python自動化測試 之 DrissionPage 使用詳解 &#x1f3e1;前言&#xff1a;一、??DrissionPage的基本概述二、 &#x1f5fa;?環境安裝2.1 ???運行環境2.2 ???一鍵安裝 三、&#x1f5fa;?快速入門3.1 頁面類&#x1f6f0;?ChromiumPage&#x1f6eb; SessionPage&…

【操作系統安全】任務3:Linux 網絡安全實戰命令手冊

目錄 一、基礎網絡信息獲取 1. 網絡接口配置 2. 路由表管理 3. 服務端口監控 二、網絡監控與分析 1. 實時流量監控 2. 數據包捕獲 3. 網絡協議分析 三、滲透測試工具集 1. 端口掃描 2. 漏洞利用 3. 密碼破解 四、日志審計與分析 1. 系統日志處理 2. 入侵檢測 3…

社群經濟4.0時代:開源鏈動模式與AI技術驅動的電商生態重構

摘要&#xff1a;在Web3.0技術浪潮與私域流量紅利的雙重驅動下&#xff0c;電商行業正經歷從"流量收割"到"用戶深耕"的范式轉變。本文基于社群經濟理論框架&#xff0c;結合"開源鏈動21模式"、AI智能名片、S2B2C商城小程序源碼等創新工具&#x…

從技術架構和生態考慮,不是單純的配置優化,還有哪些方式可以提高spark的計算性能

從技術架構和生態系統層面提升Spark的計算性能&#xff0c;可采取以下核心策略&#xff1a; 一、計算模型重構與執行引擎升級 1. 彈性分布式數據集&#xff08;RDD&#xff09;的血統優化 通過RDD的Lineage&#xff08;血統&#xff09;機制實現容錯時&#xff0c;采用增量式…

AI對軟件工程(software engineering)的影響在哪些方面?

AI對軟件工程&#xff08;software engineering&#xff09;的影響是全方位且深遠的&#xff0c;它不僅改變了傳統開發流程&#xff0c;還重新定義了工程師的角色和軟件系統的構建方式。以下是AI影響軟件工程的核心維度&#xff1a; 一、開發流程的智能化重構 需求工程革命 ? …

數據庫取證分析

目錄 一.多表關聯 1.一對多聯結 2.子查詢 二.數據庫示例分析 1.多表關聯 三.選擇SQL分析的原因 四.數據庫概述 五.SQL語言 一.多表關聯 1.一對多聯結 2.子查詢 二.數據庫示例分析 1.多表關聯 三.選擇SQL分析的原因 四.數據庫概述 五.SQL語言 1.select 字段

Docker 部署 Graylog 日志管理系統

Docker 部署 Graylog 日志管理系統 前言一、準備工作二、Docker Compose 配置三、啟動 Graylog 服務四、訪問 Graylog Web 界面總結 前言 Graylog 是一個開源的日志管理平臺&#xff0c;專為實時日志收集、分析和可視化設計。它支持強大的搜索功能&#xff0c;并且與 Elastics…

Matlab2024a免費版下載教程

Matlab是一個高性能的數學計算與仿真軟件&#xff0c;廣泛應用于科學計算、數據分析、算法開發以及工程繪圖等多個領域。它提供了強大的矩陣運算能力、豐富的內置函數庫以及靈活的編程環境&#xff0c;使得用戶能夠高效地解決復雜的數學問題。本文&#xff0c;我將為大家詳細介…

網絡運維學習筆記(DeepSeek優化版) 022 HCIP-Datacom路由概念、BFD協議詳解與OSPF第一課

文章目錄 路由概念、BFD協議詳解與OSPF第一課一、路由協議優先級與選路原則1.1 路由協議優先級對照表1.2 路由選路核心原則 二、BFD&#xff08;Bidirectional Forwarding Detection&#xff0c;雙向轉發檢測&#xff09;的配置與應用2.1 雙向心跳探測&#xff08;雙端配置&…

【基礎】Windows 中通過 VSCode 使用 GCC 編譯調試 C++

準備 安裝 VSCode 及 C 插件。通過 MSYS2 安裝 MinGW-w64 工具鏈&#xff0c;為您提供必要的工具來編譯代碼、調試代碼并配置它以使用IntelliSense。參考&#xff1a;Windows 中的 Linux 開發工具鏈 驗證安裝&#xff1a; gcc --version g --version gdb --version三個核心配…

python機器學習——新手入門學習筆記

一&#xff0c;概論 1.什么是機器學習 定義&#xff1a; 機器學習是從數據中自動分析獲得模型&#xff0c;并利用模型對未知數據進行預測。 其實就是通過問題和數據&#xff0c;發現規律&#xff0c;并進行預測&#xff0c;與人腦相似。目的就是從歷史數據當中獲得規律&#x…

Jackson使用ArrayNode對象實現JSON列表數據(二):增、刪、改、查

JSON數據的操作,系列文章: 《Jackson的核心類與API方法:ObjectMapper、JsonNode、ObjectNode、ArrayNode》 《Jackson的使用與創建Jackson工具類》 《Jackson使用ObjectNode對象實現JSON對象數據(一):增、刪、改、查》 《Jackson使用ArrayNode對象實現JSON列表數據(二)…

Packaging Process

Packaging Process 軟包裝流程&#xff0c;在我們自動化設備的情況下&#xff0c;最后實現自動化工具 一小盒2袋&#xff0c;一大盒3小盒&#xff0c;一大盒6袋

地理信息系統(GIS)在智慧城市中的40個應用場景案例

在智慧城市發展進程中&#xff0c;地理信息系統&#xff08;GIS&#xff09;作為關鍵技術之一&#xff0c;正扮演著不可或缺的角色&#xff0c;堪稱智慧城市的神經中樞。通過空間數據分析優化城市管理&#xff0c;GIS技術為智慧城市的構建提供了強大的支持。 本文分享了GIS在智…

在 Jenkins Pipeline 中利用 Groovy 的閉包特性創建自定義語法糖

在 Jenkins Pipeline 中利用 Groovy 的閉包特性創建自定義語法糖&#xff0c;可以讓流水線代碼更簡潔易讀。以下是實現思路和示例&#xff1a; 1. 基礎閉包方法定義 // 定義一個優雅的 stage 語法 def elegantStage(String name, Closure body) { stage(name) { ec…

【藍橋杯】每日練習 Day11 逆序對問題和多路歸并

目錄 前言 超快速排序 分析 代碼 小朋友排隊 分析 代碼 魚塘釣魚 分析 代碼 前言 本來計劃今天寫五道題的&#xff0c;結果計劃趕不上變化&#xff0c;誰能告訴我我的時間都去哪了。。。 今天給大家帶來三道題目&#xff0c;兩道逆序對問題&#xff0c;分別用歸并排…

OpenCV 圖像基本操作

之前幾篇文章介紹了OpenCV的一些模塊概念,并沒有細說每個模塊具體的方法和使用。接下來就會詳細介紹每個模塊模塊包含的方法和使用。 本文將詳細介紹圖像的四種基本操作:訪問和修改像素值、圖像 ROI (Region of Interest) 操作、圖像通道分離與合并、以及圖像的縮放、旋轉、…

酷淘商場項目【從零到一詳解】Web端

?博客主頁&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客內容》&#xff1a;.NET、Java.測試開發、Python、Android、Go、Node、Android前端小程序等相關領域知識 &#x1f4e2;博客專欄&#xff1a; https://blog.csdn.net/m0_63815035/cat…