一、JSON文件操作?
1. 核心類??
??QJsonDocument??:表示整個JSON文檔,提供解析(fromJson()
)和序列化(toJson()
)功能。
??QJsonObject??:存儲鍵值對集合,支持嵌套對象和數組。
??QJsonArray??:存儲有序值列表。
??QJsonValue??:封裝JSON支持的數據類型(字符串、數字、布爾值等)
2. 讀寫操作?
讀取JSON文件??:
QFile file("config.json");
if (!file.open(QIODevice::ReadOnly))
{return; // 錯誤處理
}
// 讀取文件
QByteArray jsonStr = file.readAll();
// 關閉文件
file.close();// 將json字符串轉化為json文檔
QJsonDocument jsonDoc = QJsonDocument::format(jsonStr);// 將json文檔轉化為json對象
QJsonObject jsonObj = jsonDoc.object();// 獲取對應的數據,獲取的類型默認值為QJsonValue
jsonObj.value("鍵").to對應的類型轉化;
寫入JSON文件??:
// 創建json對象
QJsonObject rootObj;
// 插入內容
rootObj.insert("key","value");// 將json對象轉化為json文檔
QJsonDocument jsonDoc(jsonObj);
// 將json文檔轉化為json字符串
QByteArray jsonStr = jsonDoc.toJson(QJsonDocument::Compact);
// 打開文件
QFile file("相對路徑/絕對路徑");
if(!file.open(QIODevide::WriteOnly))
{return;// 錯誤處理
}
// 寫入json字符串
file.write(jsonStr);
// 關閉文件
file.close();
二、XML文件操作?
1. 兩種處理方式對比?
??方法 | 適用場景? | ??核心類? |
---|---|---|
DOM模型 ?? | 小文件、需隨機訪問或修改 | QDomDocument, QDomNode |
?? 流式處理?? | 大文件、只需順序讀寫 | QXmlStreamReader/Writer |
2. DOM模型示例
讀取XML??:
// 1、載入xml文檔
QDomDocument doc;QFile file("相對路徑/絕對路徑");if(!file.open(QIODevice::ReadOnly))
{qDebug() << "文件打開失敗";return;
}QString errorMsg;
int errorLine, errorColumn;
if(!doc.setContent(&file, &errorMsg, &errorLine, &errorColumn))
{qDebug() << "XML解析錯誤:" << errorMsg << "at line" << errorLine << "column" << errorColumn;file.close();return;
}qDebug() << "文件讀取成功";
file.close();// 2、讀取頭部信息
QDomNode head = doc.firstChild();
qDebug() << head.nodeName() << head.nodeType() << head.nodeValue();// 3、獲取根節點
QDomElement rootEle = doc.documentElement();
qDebug() << rootEle.nodeName() << rootEle.nodeType() << rootEle.nodeValue() << rootEle.tagName();// 4、獲取name標簽
QDomElement nameEle = rootEle.firstChild().toElement();
qDebug() << nameEle.nodeName() << nameEle.nodeType() << nameEle.nodeValue();
qDebug() << nameEle.tagName() << nameEle.text() << nameEle.attribute("id") << nameEle.attribute("height");// 循環son獲取數據
QDomElement sonEle = nameEle.nextSiblingElement("son");
QDomNode node = sonEle.firstChild();while (node.isElement())
{QDomElement temp = node.toElement();qDebug() << temp.text();node = temp.nextSiblingElement();
}
讀取XML表格:
QDomDocument doc;QFile file("相對路徑/絕對路徑");
if(!file.open(QIODevice::ReadOnly))
{qDebug() << "文件打開失敗";return;
}
qDebug() << doc.setContent(&file);//通過 elementsByTagName 來獲取標簽對象
QDomNodeList namels = doc.elementsByTagName("book-name");
QDomNodeList authorls = doc.elementsByTagName("author");
QDomNodeList pricels = doc.elementsByTagName("price");
QDomNodeList pubdatels = doc.elementsByTagName("publish-date");
// 設置表格大小
ui->tableWidget->setRowCount(namels.size());
ui->tableWidget->setColumnCount(4);
ui->tableWidget->setHorizontalHeaderLabels({"書名","作者","價格","出版日期"});// 因為 nameList、authorList等鏈表的長度是一樣的,所以使用一個循環即可
for(int i = 0;i < namels.size();i++)
{QDomElement nameEle = namels.at(i).toElement();qDebug() << nameEle.tagName() << nameEle.text();QDomElement authorEle = authorls.at(i).toElement();QDomElement priceEle = pricels.at(i).toElement();QDomElement pubdateEle = pubdatels.at(i).toElement();//ui->tableWidget->setItem(i,0,new QTableWidgetItem(nameEle.nextSiblingElement().text()));ui->tableWidget->setItem(i,0,new QTableWidgetItem(nameEle.text()));ui->tableWidget->setItem(i,1,new QTableWidgetItem(authorEle.text()));ui->tableWidget->setItem(i,2,new QTableWidgetItem(priceEle.text()));ui->tableWidget->setItem(i,3,new QTableWidgetItem(pubdateEle.text()));
}file.close();
寫入XML??:
// 1、在內存當中創建doc樹
// 1.1、創建一個空的dom樹
QDomDocument doc;// 1.2、創建頭部標簽
QDomProcessingInstruction head = doc.createProcessingInstruction("xml","version='1.0' encoding='utf-8'");
// 追加給dom樹
doc.appendChild(head);// 1.3、添加跟標簽
QDomElement rootEle = doc.createElement("root");
// 追加給dom樹
doc.appendChild(rootEle);// 1.4、向根標簽中添加子標簽
QDomElement userEle = doc.createElement("user");
rootEle.appendChild(userEle);// 向子標簽添加屬性
userEle.setAttribute("id","0101");
QDomText textEle = doc.createTextNode("張無忌");
userEle.appendChild(textEle);// 2、將doc樹寫入文件
QFile file("相對路徑/絕對路徑");
if(!file.open(QIODevice::WriteOnly))
{qDebug() << "文件打開失敗";return;
}
QTextStream out(&file);
doc.save(out,4);
file.close();
3. 流式處理示例?
讀取XML??:
// 載入xml文檔,并將節點都保存為“記號”
QFile file("相對路徑/絕對路徑");
if(!file.open(QIODevice::ReadOnly))
{qDebug() << "文件打開失敗";return;
}QXmlStreamReader reader;
reader.setDevice(&file);// 循環獲得標記
while(!reader.atEnd())
{// 找到下一個記號,并保存該記號的類型QXmlStreamReader::TokenType type = reader.readNext();if(type == QXmlStreamReader::StartDocument){qDebug() << reader.documentVersion() << reader.documentEncoding();}else if(type == QXmlStreamReader::StartElement){if(reader.attributes().hasAttribute("id")){QString id = reader.attributes().value("id").toString();qDebug() << QString("<%1 id=\"%2\">").arg(reader.name()).arg(id);}else {qDebug() << QString("<%1>").arg(reader.name());}}else if(type == QXmlStreamReader::EndElement){qDebug() << QString("</%1>").arg(reader.name());}else if(type == QXmlStreamReader::Characters && !reader.isWhitespace()){qDebug() << reader.text();}
}file.close();
寫入XML??:
// 1、使用寫入流綁定一個xml文件(目的就是向文件中寫入內容)
QFile file("相對路徑/絕對路徑");
if(!file.open(QIODevice::WriteOnly))
{qDebug() << "文件打開失敗";return;
}QXmlStreamWriter writer(&file);// 2、向xml中寫入內容
// 實現自動格式化文檔
writer.setAutoFormatting(true);// 創建頭
// <?xml version="1.0" encoding="utf-8"?>
writer.writeStartDocument();// 創建第一個元素
// <user>
writer.writeStartElement("user");
// <name id="1001" height="175.8">于謙</name>
writer.writeStartElement("name");
writer.writeAttribute("id","1001");
writer.writeAttribute("height","175.8");
writer.writeCharacters("于謙");
writer.writeEndElement();// <isMarry>true</isMarry>
writer.writeTextElement("isMarray","true");// </user>
writer.writeEndElement();// 關閉文檔
writer.writeEndDocument();
// 3、關閉文件
file.close();
三、總結
-
??配置文件存儲??:
JSON:適合結構簡單、需頻繁讀寫的配置(如用戶設置)。
XML:適合復雜結構或需驗證的場景(如SOAP通信、文檔格式)。 -
??路徑管理??:
外部文件路徑用QCoreApplication::applicationDirPath()
獲取。 -
??版本兼容??:
Qt 6移除了QJsonDocument::fromBinaryData()
,優先使用文本格式