1. 程式人生 > >QT實現對資料文字儲存的辦法及其操作

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();
    }
}