QT實現對資料文字儲存的辦法及其操作
QT檔案型別
(1)文字檔案(QTextStream流):檔案內容是可讀的文字字元
(2)資料檔案(QDataStream流):檔案內容是直接的二進位制資料
QT對文字操作方式
1、QFile類,該類支援 對檔案或者是資料檔案的讀寫,提供的介面如下:
①qint64 read(char* data, qint64 maxSize);
②QByteArray read(qint64 maxSize);
③qint64 write(const char* data, qint64 maxSize);
④qint64 write(const QByteArray& byteArray);
該類暴露出來的缺點就是需要對資料型別的強制轉換;
直接用QFile讀寫的例項程式碼
#include <QCoreApplication>
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile file("C:/Users/SantaClaus/Desktop/test.hex");
if (file.open(QIODevice::WriteOnly)) //開啟方式:可讀、二進位制方式
{
QString name = "SantaClaus" ;
double value = 3.14;
//按二進位制寫入時,須進行型別轉換,這也是QFile使用上比較麻煩的地方
file.write(name.toStdString().c_str()); //引數為char*,須轉換
file.write(reinterpret_cast<char*>(&value), sizeof(value));
file.close();
}
if(file.open(QIODevice::ReadOnly)) //只讀、二進位制方式
{
QString name ="" ;
double value = 0;
//read的返回值為QByteArray,當賦值給QString變數型別時進行自動轉換
//以下語句也可以寫成name = file.read(10);
name = QString(file.read(10));
file.read(reinterpret_cast<char*>(&value), sizeof(value));
file.close();
qDebug() << name;
qDebug() << value;
}
return a.exec();
}
2、QFile結合使用輔助的檔案流QTextStream;
QTextStream:寫入的資料全部轉換為可讀檔案
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QDebug>
void textStream_test(QString f)
{
QFile file(f);
if(file.open(QIODevice::WriteOnly | QIODevice::Text)) //以文字文式寫入
{
QTextStream out(&file);
out << QString("SantaClaus") << endl;
out << QString("Result: ") << endl;
//以下故意輸入多種型別的資料,但都被自動轉換為QString型別,不需要顯式轉換!
out << 5 << "*" << 6 << '=' << 5*6 << endl;
file.close();
}
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&file);
while( !in.atEnd()) //未到檔案尾
{
QString line = in.readLine();
qDebug() << line;
}
file.close();
}
}
3、QFile類結合使用資料文字流QDataStream;
QDataStream:寫入的資料根據型別轉換為二進位制資料;
但值得注意的是:
A、不同Qt版本的資料流檔案格式可能不同,當資料流檔案需要在不同版本的Qt程式間傳遞資料時,需要考慮版本問題。
B、相關函式
void setVersion(int v); //設定讀寫版本號
int version() const //獲取讀寫版本號
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QDebug>
void dataStream_test(QString f)
{
QFile file(f);
if(file.open(QIODevice::WriteOnly)) //以二進位制方式開啟
{
QDataStream out(&file);
//設定資料流的版本,以便在不同版本的Qt間進行資料傳遞
out.setVersion(QDataStream::Qt_5_6);
out << QString("SantaClaus");
out << QString("Result: ");
out << 3.14;
file.close();
}
if (file.open(QIODevice::ReadOnly))
{
QDataStream in(&file);
QString name = "";
QString result = "";
double value = 0;
in.setVersion(QDataStream::Qt_5_6);
in >> name;
in >> result;
in >> value;
qDebug() << name;
qDebug() << result;
qDebug() << value;
}
}
小結
(1)Qt中的檔案輔助類用於方便讀寫操作
(2)QTextStream用於文字資料的快速讀寫
(3)QDataStream用於二進位制資料的快速讀寫
(4)QDataStream的檔案格式與Qt版本相關
(5)資料格式檔案在程式間傳遞時,需要考慮版本問題
流使用實用技巧
最近在搞個小專案,用QT結合Opencv做開發,需要用到將程式執行的某些引數儲存下來,採用的是文字儲存,這一次遇到的都是一些浮點的型別,一開始想讓這些浮點型別轉換為字元型別QString,這樣的方法也可以行得通,但是會損失一小些精度,且操作繁瑣,效率也不高,想到了文字流好像直接支援型別的操作,一開始嘗試了下,但是達不到我想要的理想,需要做另外一些的字元分割操作。反反覆覆對檔案進行了操作,不斷的除錯,最後瞭解到了檔案流操作的規律。
起初的程式碼:
儲存資料到文字檔案中。
#define SAVE_DATA "J_SAVE.dat"
double XX_Angle;
CvPoint2D32f OffsetPos;
void MainWindow::saveData()
{
QFile ExpandData(SAVE_DATA);
if(ExpandData.open(QIODevice::WriteOnly))
{
/*文字輸出流,用於儲存資料*/
QTextStream Out(&ExpandData);
Out << XX_Angle;
Out << OffsetPos.x;
Out << OffsetPos.y;
ExpandData.close();
}
}
從文字檔案上載入之前儲存的資料
#define SAVE_DATA "J_SAVE.dat"
double XX_Angle;
CvPoint2D32f OffsetPos;
void MainWindow::loadData()
{
QFile ExpandData(SAVE_DATA);
if(ExpandData.open(QIODevice::ReadOnly))
{
/*文字輸出流,用於儲存資料*/
QTextStream In(&ExpandData);
In >> XX_Angle;
In >> OffsetPos.x;
In >> OffsetPos.y;
ExpandData.close();
}
}
上面的程式碼測試的結果是:寫和讀不對稱,寫入的東西以同樣形式,資料型別對稱的形式來讀取不能實現對稱。最後找到原因是文字檔案流一次流讀取是以一個空格為結束的,找到這個規律之後,我在寫入的資料的時候做了一些額外操作,新增空格。
下面是調通之後的程式碼,可以盡情享用C++ 流帶來的方便快速。
#define SAVE_DATA "J_SAVE.dat"
double XX_Angle;
CvPoint2D32f OffsetPos;
/*實現儲存程式執行的資料*/
void MainWindow::saveData()
{
QFile ExpandData(SAVE_DATA);
if(ExpandData.open(QIODevice::WriteOnly))
{
/*文字輸出流,用於儲存資料*/
QTextStream Out(&ExpandData);
/*加入空格的好處是以流的形式讀取恰好是相反的操作,這樣一來方便快速對引數的讀取*/
Out << XX_Angle;
Out << ' ';
Out << OffsetPos.x;
Out << ' ';
Out << OffsetPos.y;
ExpandData.close();
}
}
/*載入程式執行時儲存的資料*/
void MainWindow::loadData()
{
QFile ExpandData(SAVE_DATA);
if(ExpandData.open(QIODevice::ReadOnly))
{
/*文字輸出流,用於儲存資料*/
QTextStream In(&ExpandData);
In >> XX_Angle;
In >> OffsetPos.x;
In >> OffsetPos.y;
ExpandData.close();
}
}