對於純綷的二進位資料,可以使用QDataStream來協助處理,可以直接處理C++基本資料型態、還有許多Qt資料型態,像是QByteArray、QString、QMap等,可以使用 << 或 >> 運算子來進行資料輸出或寫入。
先使用以下的簡單例子,示範一下QDataStream搭配QFile來進行檔案讀寫:
#include <QFile> #include <QDataStream> #include <QString> #include <QMap> #include <iostream> using namespace std;
int main(int argc, char *argv[]) { QFile file("data.dat"); QMap<QString, int> map; map.insert("caterpillar", 95); map.insert("momor", 93); if(!file.open(QIODevice::WriteOnly)) { cerr << "Cannot open file for writing: " << qPrintable(file.errorString()) << endl; return false; } QDataStream out(&file); // 設定QDataStream支援版本 out.setVersion(QDataStream::Qt_4_3); // 寫入資料 out << 1 << map; file.close(); if(!file.open(QIODevice::ReadOnly)) { cerr << "Cannot open file for reading: " << qPrintable(file.errorString()) << endl; return false; } QDataStream in(&file); // 設定QDataStream支援版本 in.setVersion(QDataStream::Qt_4_3); int num = 0; QMap<QString, int> inMap;
// 讀入資料 in >> num >> inMap;
cout << "num: " << num << endl << "map: <caterpillar, " << inMap.value("caterpillar") << ">" << endl << "map: <momor, " << inMap.value("momor") << ">" << endl; return true; }
程式中可以看到setVersion()方法,這設定QDataStream讀寫時的版本,因為Qt的物件成員等資料,會隨著不同版本而可能有所不同,例如QMap新版中可能有一些成員屬性是舊版本所沒有的,使用setVesrion()設定Qt支援的讀寫版本,告訴QDataStream在寫入或讀取時應當處理的物件資料。
程式執行時的結果如下所示:
num: 1
map: <caterpillar, 95>
map: <momor, 93>
|
QDataStream也可以直接處理位元資料,例如使用
readRawBytes()與writeRawBytes()來進行原始位元資料的處理。QDataStream處理數值時,預設使用big-
endian的方式,如果您要改變為使用little-endian,則可以使用setByteOrder()方法設定為QDataStream::
LittleEndian。
如果想要QDataStream可以使用 << 或 >> 來支援您的自訂義物件,則您需要重載 << 與 >> 運算子,告訴QDataStream如何儲存或讀取物件,例如:
#include <QFile> #include <QDataStream> #include <QString> #include <iostream> using namespace std;
class Dog { public: Dog() { _number = 0; } Dog(int number, const QString &name) { _number = number; _name = name; } void setNumber(int number) { _number = number; } int number() const { return _number; } void setName(const QString &name) { _name = name; } QString name() const { return _name; }
private: int _number; QString _name; };
QDataStream &operator<<(QDataStream &out, const Dog &dog) { out << dog.number() << dog.name(); return out; }
QDataStream &operator>>(QDataStream &in, Dog &dog) { int number = 0; QString name; in >> number >> name; dog.setNumber(number); dog.setName(name);
return in; }
int main(int argc, char *argv[]) { QFile file("data.dat"); Dog dog1(1, "caterpillar"); Dog dog2(2, "momor"); if(!file.open(QIODevice::WriteOnly)) { cerr << "Cannot open file for writing: " << qPrintable(file.errorString()) << endl; return false; } QDataStream out(&file); out.setVersion(QDataStream::Qt_4_3); out << dog1 << dog2; file.close(); if(!file.open(QIODevice::ReadOnly)) { cerr << "Cannot open file for reading: " << qPrintable(file.errorString()) << endl; return false; } QDataStream in(&file); in.setVersion(QDataStream::Qt_4_3); in >> dog1 >> dog2;
cout << dog1.number() << ", " << qPrintable(dog1.name()) << endl << dog2.number() << ", " << qPrintable(dog2.name()) << endl; return true; }
程式執行時的結果如下所示:
如以上重載 << 與 >> 運算子,還有一個好處,就是可以讓自定義物件支援QList等容器之 << 與 >> 之附加與取出,例如像以下的操作:
QList<Dog> list;
Dog dog1(1, "caterpillar");
Dog dog2(2, "momor");
list << dog1 << dog2;
QList<Dog>::const_iterator iterator = list.begin();
while(iterator != list.end()) {
cout << (*iterator).number() << ", "
<< qPrintable((*iterator).name()) << endl;
++iterator;
}
|
|