首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Qt 學習之路(56):二進制文件讀寫——QDataStream 實戰與版本兼容策略

     編輯:關於C語言

Qt IO 體系概覽

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。
  • quint32:平台無關 32 位無符號整數,確保二進制佈局一致。
  • setVersion():Qt 不同版本可能改變序列化格式(字節序、類型大小等),必須顯式指定寫入版本。
  • 運算符重載:<< 支持 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;

總結

  1. 二進制 IO 核心:QFile + QDataStream,設置 setVersion。
  2. 文件頭必含魔術數字 + 版本號,實現前向/後向兼容。
  3. 讀寫順序嚴格對應,任何增減字段需版本號配合。
  4. qPrintable() 或 QString::toStdString() 配合 std::cerr 輸出錯誤信息。

本文出自 “豆子空間” 博客,原文地址:https://devbean.blog.51cto.com/448512/293892

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved