亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

QT中QDataStream二進(jìn)制數(shù)據(jù)讀寫(xiě)的實(shí)現(xiàn)

 更新時(shí)間:2022年08月22日 09:58:25   作者:求道玉  
本文主要介紹了QT中QDataStream二進(jìn)制數(shù)據(jù)讀寫(xiě)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

Qt中的QDataStream類(lèi)為我們的程序提供了讀寫(xiě)二進(jìn)制數(shù)據(jù)的能力。一個(gè)數(shù)據(jù)流如果是二進(jìn)制編碼的數(shù)據(jù)流,那么它肯定是與計(jì)算機(jī)的操作系統(tǒng)、CPU或者字節(jié)序無(wú)關(guān)的。例如,一個(gè)數(shù)據(jù)流是在一個(gè)運(yùn)行Windows系統(tǒng)的PC機(jī)上被寫(xiě)入的,那么它照樣可以在一臺(tái)運(yùn)行Solaris的Sun SPARC的機(jī)器上被讀取出來(lái)。同樣,我們也可以使用QDataStream去讀寫(xiě)原生的未編碼的二進(jìn)制數(shù)據(jù)。

QDataStream類(lèi)實(shí)現(xiàn)了序列化C++的基本數(shù)據(jù)類(lèi)型的功能,比如char,short,int,char* 等等。如果要序列化更復(fù)雜的數(shù)據(jù)類(lèi)型,可以將復(fù)雜數(shù)據(jù)類(lèi)型分解成獨(dú)立的基本數(shù)據(jù)類(lèi)型分別進(jìn)行序列化。

一個(gè)數(shù)據(jù)流往往需要一個(gè)QIODevice配合使用。因?yàn)镼IODevice代表了一個(gè)可以從中讀取數(shù)據(jù)或向其寫(xiě)入數(shù)據(jù)的輸入輸出設(shè)備。我們最常常見(jiàn)的QFile文件類(lèi)就是一種QIODevice。下面我們先分別看一個(gè)使用QDataStream進(jìn)行二進(jìn)制數(shù)據(jù)讀寫(xiě)的例子。

write binary data to a stream:

  QFile file("file.dat");
  file.open(QIODevice::WriteOnly);
  QDataStream out(&file);   // we will serialize the data into the file
  out << QString("the answer is");   // serialize a string
  out << (qint32)42;        // serialize an integer

read binary data from a stream:

  QFile file("file.dat");
  file.open(QIODevice::ReadOnly);
  QDataStream in(&file);    // read the data serialized from the file
  QString str;
  qint32 a;
  in >> str >> a;           // extract "the answer is" and 42

每一項(xiàng)被寫(xiě)入的數(shù)據(jù),都是按一種預(yù)定義的二進(jìn)制格式寫(xiě)入的,改格式取決于具體每一項(xiàng)的類(lèi)型。而QDataStream支持的類(lèi)型包括QBrush,QColor,QDateTime等等。

特別注意,對(duì)應(yīng)整數(shù)來(lái)說(shuō),在寫(xiě)入時(shí)最好轉(zhuǎn)換成Qt中的某種整數(shù)類(lèi)型,讀取時(shí)也讀取為同樣的Qt整數(shù)類(lèi)型。這可以確保得到正確大小的整數(shù)并且可以屏蔽掉不同編譯器和平臺(tái)之間的差異。舉個(gè)栗子,對(duì)于一個(gè)char* 字符串來(lái)說(shuō),先寫(xiě)入一個(gè)32-bit的整數(shù)值,該值就是字符串的長(zhǎng)度,包括'\0',緊接著是字符串中 的每一個(gè)字符,包括'\0'。當(dāng)讀取時(shí),也是這樣操作,寫(xiě)讀取4字節(jié)創(chuàng)建出一個(gè)32-bit的字符串長(zhǎng)度值,然后再根據(jù)創(chuàng)建出的長(zhǎng)度值讀取出相應(yīng)個(gè)數(shù)的字符,包括'\0'。

版本

QDataStream的二進(jìn)制格式從Qt1.0就開(kāi)始形成了,很有可能在將來(lái)繼續(xù)進(jìn)化已反應(yīng)Qt的變化。當(dāng)操作復(fù)雜數(shù)據(jù)類(lèi)型時(shí),我們就要確保讀取和寫(xiě)入時(shí)的QDataStream版本是一樣的。如果你需要向前和向后兼容,可以在代碼中使用硬編碼指定流的版本號(hào):

stream.setVersion(QDataStream::Qt_4_0);

如果你正在創(chuàng)建一種新的二進(jìn)制數(shù)據(jù)格式,比如作為你的應(yīng)用程序創(chuàng)建的文件的格式,你可以使用QDataStream以一種可移植的格式去寫(xiě)入這些數(shù)據(jù)。典型情況下,你可能會(huì)在文件頭寫(xiě)入一個(gè)簡(jiǎn)短的幻數(shù)字符串和一個(gè)版本數(shù)字,來(lái)用于將來(lái)擴(kuò)展。例如:

  QFile file("file.xxx");
  file.open(QIODevice::WriteOnly);
  QDataStream out(&file);
 
  // Write a header with a "magic number" and a version
  out << (quint32)0xA0B0C0D0;
  out << (qint32)123;
 
  out.setVersion(QDataStream::Qt_4_0);
 
  // Write the data
  out << lots_of_interesting_data;

那么,我們就可以以下面這種方式來(lái)讀?。?/p>

  QFile file("file.xxx");
  file.open(QIODevice::ReadOnly);
  QDataStream in(&file);
 
  // Read and check the header
  quint32 magic;
  in >> magic;
  if (magic != 0xA0B0C0D0)
      return XXX_BAD_FILE_FORMAT;
 
  // Read the version
  qint32 version;
  in >> version;
  if (version < 100)
      return XXX_BAD_FILE_TOO_OLD;
  if (version > 123)
      return XXX_BAD_FILE_TOO_NEW;
 
  if (version <= 110)
      in.setVersion(QDataStream::Qt_3_2);
  else
      in.setVersion(QDataStream::Qt_4_0);
 
  // Read the data
  in >> lots_of_interesting_data;
  if (version >= 120)
      in >> data_new_in_XXX_version_1_2;
  in >> other_interesting_data;

同時(shí),還可以在序列化數(shù)據(jù)時(shí)指定一個(gè)字節(jié)序。默認(rèn)情況下是big endian。除非特殊需求,我們一個(gè)建議保持這個(gè)設(shè)置的默認(rèn)值,不做修改。

讀寫(xiě)原生二進(jìn)制數(shù)據(jù)

有時(shí),我們希望直接從data stream里讀取原生的二進(jìn)制數(shù)據(jù)。此時(shí),可以使用readRawData() 將數(shù)據(jù)讀入一個(gè)預(yù)先分配好的char*;同樣的數(shù)據(jù)也可以使用writeRawData() 函數(shù)寫(xiě)入data stream。但要記住,使用這種方式的話(huà),要由你自己進(jìn)行所有數(shù)據(jù)的編碼和解碼。于此類(lèi)似的另外兩個(gè)函數(shù)是readBytes() 和 writeBytes()。這兩個(gè)函數(shù)與上面的Raw版本相比,區(qū)別主要是:readBytes() 先讀取一個(gè)quint32值,該值被當(dāng)做將要讀取的數(shù)據(jù)的長(zhǎng)度,然后讀取相應(yīng)字節(jié)的數(shù)據(jù)到預(yù)先定義好的char*中;writeBytes() 也同理,先寫(xiě)入一個(gè)quint32的數(shù)據(jù)長(zhǎng)度值,緊接著寫(xiě)入相應(yīng)數(shù)據(jù)。同樣,使用這兩個(gè)函數(shù),所以數(shù)據(jù)的編碼和解碼要有我們自己負(fù)責(zé)。注意,readBytes() 不需要我們事先分配好內(nèi)存, 而readRawData() 需要我們事先分配好內(nèi)存。

讀寫(xiě)Qt集合類(lèi)和其他Qt類(lèi)

Qt的常見(jiàn)集合類(lèi)也可以使用QDataStream進(jìn)行序列化,這包括QList,QLinkedList,QVector,QSet,QHash和QMap。不過(guò),序列化這些類(lèi)的流操作符不是這個(gè)類(lèi)的成員函數(shù)而已。同理,讀寫(xiě)Qt中的其他類(lèi)型,比如QImage,也是可以的。

使用事務(wù)

當(dāng)在一個(gè)異步的設(shè)備上讀取數(shù)據(jù)時(shí),數(shù)據(jù)塊可以在任意的時(shí)間點(diǎn)上到來(lái)。所以,為了應(yīng)對(duì)這種情況,QDataStream提供了一個(gè)事務(wù)機(jī)制來(lái)確保原子性的完成一系列的流操作符。例如,你可以在操作socket時(shí),在相應(yīng)readyRead() 的槽函數(shù)中,使用事務(wù)來(lái)完成不完整的數(shù)據(jù)讀取。

  in.startTransaction();
  QString str;
  qint32 a;
  in >> str >> a; // try to read packet atomically
 
  if (!in.commitTransaction())
      return;     // wait for more data

如果沒(méi)有完整的數(shù)據(jù)包到來(lái),commitTransaction() 會(huì)返回false,并將stream重置為初始狀態(tài),然后,等待更多數(shù)據(jù)的到來(lái)。

下面給出一個(gè)簡(jiǎn)單的測(cè)試程序:

#include <QCoreApplication>
#include <QDebug>
#include <QDataStream>
#include <QFile>
#include <QVector>
#include <QMap>
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    //write
    QFile file("test.dat");
    if (!file.open(QIODevice::ReadWrite))
    {
        qDebug() << "open file failed";
        return 0;
    }
    QDataStream ds(&file);
    const char *wstr = "hello-world";
    quint32 wi = 1234;
    double wd = 1.1;
    float wf = 2.2f;
    QVector<int> wvector;
    wvector.push_back(1);
    wvector.push_back(2);
    wvector.push_back(3);
    QMap<int,int> wmap;
    wmap.insert(4, 4);
    wmap.insert(5, 5);
    wmap.insert(6, 6);
    ds << wstr;
    ds << wi;
    ds << wd;
    ds << wf;
    ds << wvector;
    ds << wmap;
    ds.writeBytes("file end ", qstrlen("file end "));
    ds.writeRawData("really end", qstrlen("really end"));
 
    //read
    file.seek(0);
    char *rstr;
    quint32 ri;
    double rd;
    float rf;
    QVector<int> rvector;
    QMap<int, int> rmap;
    char *rbytes;
    uint len;
    char *rraw = new char[100]{0};
    int rlen;
    ds >> rstr;
    ds >> ri;
    ds >> rd;
    ds >> rf;
    ds >> rvector;
    ds >> rmap;
    ds.readBytes(rbytes, len);
    ds.readRawData(rraw, rlen);
    qDebug() << rstr;
    qDebug() << ri;
    qDebug() << rd;
    qDebug() << rf;
    qDebug() << rvector;
    qDebug() << rmap;
    qDebug() << rbytes;
    qDebug() << rraw;
 
    return a.exec();
}

到此這篇關(guān)于QT中QDataStream二進(jìn)制數(shù)據(jù)讀寫(xiě)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)QT QDataStream二進(jìn)制數(shù)據(jù)讀寫(xiě)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言的strcpy函數(shù)你了解嗎

    C語(yǔ)言的strcpy函數(shù)你了解嗎

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的strcpy函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C++學(xué)習(xí)之函數(shù)模板的使用詳解

    C++學(xué)習(xí)之函數(shù)模板的使用詳解

    函數(shù)模板可以適用泛型來(lái)定義函數(shù),其中泛型可以是(int, double, float)等替換。這篇文章主要來(lái)和大家聊聊函數(shù)模板的具體使用,感興趣的可以了解一下
    2023-03-03
  • 常用的C++標(biāo)準(zhǔn)庫(kù)頭文件小結(jié)

    常用的C++標(biāo)準(zhǔn)庫(kù)頭文件小結(jié)

    C++標(biāo)準(zhǔn)庫(kù)定義了一系列函數(shù)、宏和對(duì)象,以實(shí)現(xiàn)跨團(tuán)隊(duì)、跨平臺(tái)的高效且具有卓越性能的標(biāo)準(zhǔn)化 C++ 代碼, 本文介紹常用的C++標(biāo)準(zhǔn)庫(kù)頭文件,需要的朋友可以參考下
    2023-11-11
  • matlab?GUI指紋識(shí)別門(mén)禁系統(tǒng)介紹及源碼實(shí)現(xiàn)

    matlab?GUI指紋識(shí)別門(mén)禁系統(tǒng)介紹及源碼實(shí)現(xiàn)

    這篇文章主要為大家介紹了matlab?GUI指紋識(shí)別門(mén)禁系統(tǒng)的介紹及源碼實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • C++結(jié)構(gòu)體數(shù)組詳細(xì)解析

    C++結(jié)構(gòu)體數(shù)組詳細(xì)解析

    定義結(jié)構(gòu)體數(shù)組和定義結(jié)構(gòu)體變量類(lèi)似,定義結(jié)構(gòu)體數(shù)組時(shí)只需聲明其為數(shù)組即可
    2013-10-10
  • C++類(lèi)的返回值是*this的成員函數(shù)問(wèn)題

    C++類(lèi)的返回值是*this的成員函數(shù)問(wèn)題

    這篇文章主要介紹了C++類(lèi)的返回值是*this的成員函數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++變量和基本類(lèi)型詳解

    C++變量和基本類(lèi)型詳解

    這篇文章主要介紹了C++變量和基本類(lèi)型,,一定要注意局部變量與全局變量的作用范圍,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-10-10
  • Dev C++編譯時(shí)運(yùn)行報(bào)錯(cuò)source file not compile問(wèn)題

    Dev C++編譯時(shí)運(yùn)行報(bào)錯(cuò)source file not compile問(wèn)題

    這篇文章主要介紹了Dev C++編譯時(shí)運(yùn)行報(bào)錯(cuò)source file not compile問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Qt實(shí)現(xiàn)字符串生成二維碼功能

    Qt實(shí)現(xiàn)字符串生成二維碼功能

    這篇文章主要介紹了如何利用Qt實(shí)現(xiàn)字符串生成二維碼功能,文中的實(shí)現(xiàn)過(guò)程講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定的幫助,需要的可以參考一下
    2022-01-01
  • C語(yǔ)言數(shù)組的各種操作梳理

    C語(yǔ)言數(shù)組的各種操作梳理

    數(shù)組是一組有序的數(shù)據(jù)的集合,數(shù)組中元素類(lèi)型相同,由數(shù)組名和下標(biāo)唯一地確定,數(shù)組中數(shù)據(jù)不僅數(shù)據(jù)類(lèi)型相同,而且在計(jì)算機(jī)內(nèi)存里連續(xù)存放,地址編號(hào)最低的存儲(chǔ)單元存放數(shù)組的起始元素,地址編號(hào)最高的存儲(chǔ)單元存放數(shù)組的最后一個(gè)元素
    2022-04-04

最新評(píng)論