QIODevice 為抽象基類,派生出:
QFile、QTemporaryFile、QBuffer(支持 seek())。QProcess、QTcpSocket、QUdpSocket、QSslSocket(單向流)。上層封裝兩種流:
QDataStream —— 二進制,跨平台字節序/類型大小自動處理。QTextStream —— 文本,編碼/換行符自動轉換。
QImage image("philip.png");
QMap<QString, QColor> map;
map.insert("red", Qt::red);
map.insert("green", Qt::green);
map.insert("blue", Qt::blue);
QFile file("facts.dat");
if (!file.open(QIODevice::WriteOnly)) {
qWarning("Cannot open file for writing: %s", qPrintable(file.errorString()));
return;
}
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_3); // 關鍵:鎖定序列化版本
// 魔術數字 + 版本號 + 業務數據
out << quint32(0x12345678) << image << map;
0x12345678 標識文件格式,讀取時先校驗。Java class 用 0xCAFEBABE。<< 支持 C++ 基本類型、Qt 核心類型(QString、QImage、QMap 等)及容器。
quint32 magic;
QImage image;
QMap<QString, QColor> map;
QFile file("facts.dat");
if (!file.open(QIODevice::ReadOnly)) { /* 錯誤處理 */ return; }
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_3); // 必須與寫入版本一致
in >> magic >> image >> map;
if (magic != 0x12345678) { /* 格式不匹配 */ return; }
// 使用 image、map...
硬編碼 setVersion 會導致無法利用新版 Qt 特性。解決方案:文件頭寫入自定義版本號,讀取時動態選擇 setVersion。
QFile file("file.xxx");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
// 文件頭:魔術數字 + 文件版本
out << quint32(0xA0B0C0D0) << qint32(123); // 版本 123
// 根據版本選擇 Qt 序列化版本
out.setVersion(QDataStream::Qt_4_0);
// 業務數據
out << lots_of_interesting_data;
QFile file("file.xxx");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
// 1. 校驗魔術數字
quint32 magic; in >> magic;
if (magic != 0xA0B0C0D0) return BAD_FORMAT;
// 2. 讀取文件版本
qint32 version; in >> version;
if (version < 100) return TOO_OLD;
if (version > 123) return TOO_NEW;
// 3. 動態選擇 Qt 序列化版本
if (version <= 110)
in.setVersion(QDataStream::Qt_3_2);
else
in.setVersion(QDataStream::Qt_4_0);
// 4. 讀取通用數據
in >> lots_of_interesting_data;
// 5. 版本相關的新字段條件讀取
if (version >= 120)
in >> data_new_in_v1_2;
in >> other_data;
QFile + QDataStream,設置 setVersion。qPrintable() 或 QString::toStdString() 配合 std::cerr 輸出錯誤信息。本文出自 “豆子空間” 博客,原文地址:https://devbean.blog.51cto.com/448512/293892