• QDataStream类参考(串行化数据,可设置低位高位,以及版本号),还有一个例子


    QDataStream类提供了二进制数据到QIODevice的串行化。

    #include

    所 有成员函数的列表。

    公有成员

    • QDataStream ()
    • QDataStream ( QIODevice * d )
    • QDataStream ( QByteArray a, int mode )
    • virtual ~QDataStream ()
    • QIODevice * device () const
    • void setDevice ( QIODevice * d )
    • void unsetDevice ()
    • bool atEnd () const
    • bool eof () const (obsolete)
    • enum ByteOrder { BigEndian, LittleEndian }
    • int byteOrder () const
    • void setByteOrder ( int bo )
    • bool isPrintableData () const
    • void setPrintableData ( bool enable )
    • int version () const
    • void setVersion ( int v )
    • QDataStream & operator>> ( Q_INT8 & i )
    • QDataStream & operator>> ( Q_UINT8 & i )
    • QDataStream & operator>> ( Q_INT16 & i )
    • QDataStream & operator>> ( Q_UINT16 & i )
    • QDataStream & operator>> ( Q_INT32 & i )
    • QDataStream & operator>> ( Q_UINT32 & i )
    • QDataStream & operator>> ( Q_LONG & i )
    • QDataStream & operator>> ( Q_ULONG & i )
    • QDataStream & operator>> ( float & f )
    • QDataStream & operator>> ( double & f )
    • QDataStream & operator>> ( char *& s )
    • QDataStream & operator<< ( Q_INT8 i )
    • QDataStream & operator<< ( Q_UINT8 i )
    • QDataStream & operator<< ( Q_INT16 i )
    • QDataStream & operator<< ( Q_UINT16 i )
    • QDataStream & operator<< ( Q_INT32 i )
    • QDataStream & operator<< ( Q_UINT32 i )
    • QDataStream & operator<< ( Q_LONG i )
    • QDataStream & operator<< ( Q_ULONG i )
    • QDataStream & operator<< ( float f )
    • QDataStream & operator<< ( double f )
    • QDataStream & operator<< ( const char * s )
    • QDataStream & readBytes ( char *& s, uint & l )
    • QDataStream & readRawBytes ( char * s, uint len )
    • QDataStream & writeBytes ( const char * s, uint len )
    • QDataStream & writeRawBytes ( const char * s, uint len )

    详细描述

    QDataStream类提供了二进制数据到QIODevice的串行化。

    数据流是一个编码信息的二进制流,它与主机的操作系统、CPU或字节顺序100%的没有关系。比如一个在PC的Windows下写的数据流可以在Sun SPARC的Solaris中读出。

    QTextStream.你也可以使用一个数据流来读/写原始的未编码的二进制数据。如果你想“解析”输入流,请参考QTextStream。

    QDataStream类实现了基本类型的串行化,比如char、short、int、char*等等。更加复杂的类型的串行化是通过把数据分解为简单单元来实现的。

    数据流和QIODevice合作非常紧密。QIODevice描述了一个可以从中读数据和向它写数据的输入/输出介质。QFile类就是一个IO设备的例子。

    实例(向一个流中写二进制数据):

    QFile f( "file.dta" );

    f.open( IO_WriteOnly );

    QDataStream s( &f ); // 我们将把数据串行化至文件f

    s << "the answer is"; // 串行化一个字符串

    s << (Q_INT32)42; // 串行化一个整数

    实例(从一个流中读二进制数据):

    QFile f( "file.dta" );

    f.open( IO_ReadOnly );

    QDataStream s( &f ); // 从文件f中读取串行化的数据

    QString str;

    Q_INT32 a;

    s >> str >> a; // 提取出“the answer is”和42

    每一个要写到流中的项都被写成一种预定义的二进制格式,这种格式取决于这个项的类型。Qt中支持的类型有QBrush、QColor、QDateTime、QFont、QPixmap、QString、QVariant和其它一些。支持数据流的所有的Qt类型的列表请看QDataStream操作符的格式。

    举个例子,char*字符串被写做一个等于包括NUL字节的字符串长度的32位整数,后面跟着字符串中包括NUL字节的所有字节。当读取char*char*字符串中。字符串的时候,先读4个字节创建一个32位长度值,然后读取包括NUL的这么多的字节到

    初始的IODevice通常在构造函数中设置,但是也可以使用setDevice()来改变。如果你到达了数据的终点(或者如果没有IODevice被设置),atEnd()将返回真。

    如果你希望数据和以前版本的Qt一致,请使用setVersion()。

    如果你希望数据是人们可读的,比如,用于调试,你可以用setPrintableData()设置数据流为可打印数据模式。然后这个数据写起来慢一些,并且膨胀起来但已经是人们可以读取的格式了。

    如果你正在生成一种新的二进制数据格式,比如是你的应用程序创建的一种文档的文件格式,你可以使用QDataStream来把数据写成一种可移植的格式。通常,你可以写一个包含幻数字符串和版本信息的简要的头信息,这样可以给你以后的扩展提供一定的空间。比如:

    QFile f( "file.xxx" );

    f.open( IO_WriteOnly );

    QDataStream s( &f );



    // 写一个含有“幻数”和版本号的头

    s << (Q_UINT32)0xa0b0c0d0;

    s << (Q_INT32)123;



    // 写数据

    s << [lots of interesting data]

    然后这样读:

    QFile f( "file.xxx" );

    f.open( IO_ReadOnly );

    QDataStream s( &f );



    // 读取并检查头

    Q_UINT32 magic;

    s >> magic;

    if ( magic != 0xa0b0c0d0 )

    return XXX_BAD_FILE_FORMAT;



    // 读取版本号

    Q_INT32 version;

    s >> version;

    if ( version < 100 )

    return XXX_BAD_FILE_TOO_OLD;

    if ( version > 123 )

    return XXX_BAD_FILE_TOO_NEW;

    if ( version <= 110 )

    s.setVersion(1);



    // 读取数据

    s >> [很多有趣的数据];

    if ( version > 120 )

    s >> [在1.2版中的新数据XXX];

    s >> [其它有趣的数据];

    你串行化数据的时候,你可以选择你要使用的字节顺序。默认的设置是高字节在前。把它改变为低字节在前会破坏可移植性(除非读取程序也是用低字节在前)。我们建议你使用默认设置,除非你有特殊需要。

    读写原始二进制数据

    你也许希望把你自己的原始二进制数据直接写到数据流中,或者从数据流中直接读取它们。数据可以使用readRawBytes()从流中读取到一个预先分配好的char*。同样地也可以使用writeRawBytes()把数据写到流中。注意,任何数据的编码/解码就只能由你自己来完成了。

    一对相似的函数readBytes()和writeBytes()。它们与操作原始数据的那两个的区别是:readBytes()先读取可读的数据长度到一个Q_UINT32,然后读取这个数量的字节到已经预先分配空间的char*;writeBytes()写一个包含数据长度的Q_UNIT32,然后再是数据。注意任何数据的编码/解码(除了长度Q_UINT32)都必须由你自己来做。

    也可以参考QTextStream、QVariant和输入/输出和网络。


    成员类型文档

    QDataStream::ByteOrder

    读/写数据时使用的字节顺序。

    • QDataStream::BigEndian - 高位在前(默认的)
    • QDataStream::LittleEndian - 低位在前

    成员函数文档

    QDataStream::QDataStream ()

    构造一个没有IO设备的数据流。

    也可以参考setDevice()。

    QDataStream::QDataStream ( QIODevice * d )

    构造一个使用IO设备d的数据流。

    警告:如果你使用QSocket或QSocketDevice来作为IO设备d进行读数据,为了确保操作能够成功地执行,你必须确认在套接字提供了足够的数据,QDataStream没有任何方法来处理和恢复这种读取缺少地情况。

    也可以参考setDevice() and device().

    QDataStream::QDataStream ( QByteArray a, int mode )

    构造一个通过内置的QBuffer设备来操作一个字节数组a的数据流。mode就是QIODevice::mode(),通常不是IO_ReadOnly就是IO_WriteOnly。

    实例:

    static char bindata[] = { 231, 1, 44, ... };

    QByteArray a;

    a.setRawData( bindata, sizeof(bindata) ); // a指向bindata

    QDataStream s( a, IO_ReadOnly ); // 打开a的数据

    s >> [something]; // 读取原始的bindata

    a.resetRawData( bindata, sizeof(bindata) ); // 完成

    QByteArray::setRawData()函数不是提供给没有经验的人的。

    QDataStream::~QDataStream () [虚]

    销毁这个数据流。

    析构函数对当前的IO设备没有任何效果,除非他是一个通过构造函数传递的一个处理QByteArray的内部IO设备,这种情况下,内部IO设备被销毁。。

    bool QDataStream::atEnd () const

    如果IO设备已经到达终点(流或文件的终点),或者如果没有IO设备被设置,返回真,否则返回假,比如,如果IO设备当前位置在终点之前。

    也可以参考QIODevice::atEnd()。

    int QDataStream::byteOrder () const

    返回当前字节顺序设置——不是BigEndian就是LittleEndian

    也可以参考setByteOrder()。

    QIODevice * QDataStream::device () const

    返回当前设置的IO设备。

    也可以参考setDevice()和unsetDevice()。

    bool QDataStream::eof () const

    这个函数是废弃的。它的提供只是为了保证旧代码能够工作。我们强烈建议在新代码中不要使用它。

    如果IO设备到达终点(流或文件的终点),或者如果没有IO设备被设置,返回真。

    如果当前的IO的读写位置在终点之前,返回假。

    也可以参考QIODevice::atEnd()。

    bool QDataStream::isPrintableData () const

    如果可打印数据标记已经被设定,返回真。

    也可以参考setPrintableData()。

    QDataStream & QDataStream::operator<< ( Q_INT8 i )

    写一个有符号的字节i

    到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( Q_UINT8 i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个无符号的字节i到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( Q_INT16 i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个有符号的16位整数i到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( Q_UINT16 i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个无符号的16位整数i到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( Q_INT32 i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个有符号的32位整数i到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( Q_UINT32 i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个无符号的32位整数i到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( Q_LONG i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个有符号的,长度为系统字长度的整数i到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( Q_ULONG i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个无符号的,长度为系统字长度的整数i到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( float f )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个使用标准IEEE754格式的32位浮点数f到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( double f )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个使用标准IEEE754格式的64位浮点数f到流中并返回流的引用。

    QDataStream & QDataStream::operator<< ( const char * s )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    写一个以“/0”结尾的字符串s到流中并返回流的引用。

    这个字符串是使用writeBytes()串行化的。

    QDataStream & QDataStream::operator>> ( Q_INT8 & i )

    从流中读取一个有符号的字节到i

    并返回流的引用。

    QDataStream & QDataStream::operator>> ( Q_UINT8 & i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个无符号的字节到i并返回流的引用。

    QDataStream & QDataStream::operator>> ( Q_INT16 & i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个有符号的16位整数到i并返回流的引用。

    QDataStream & QDataStream::operator>> ( Q_UINT16 & i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个无符号的16位整数到i并返回流的引用。

    QDataStream & QDataStream::operator>> ( Q_INT32 & i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个有符号的32位整数到i并返回流的引用。

    QDataStream & QDataStream::operator>> ( Q_UINT32 & i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个无符号的32位整数到i并返回流的引用。

    QDataStream & QDataStream::operator>> ( Q_LONG & i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个有符号的,长度为系统字长度的整数到i并返回流的引用。

    QDataStream & QDataStream::operator>> ( Q_ULONG & i )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个无符号的,长度为系统字长度的整数到i并返回流的引用。

    QDataStream & QDataStream::operator>> ( float & f )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个使用标准IEEE754格式的32位浮点数到f并返回流的引用。

    QDataStream & QDataStream::operator>> ( double & f )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个使用标准IEEE754格式的64位浮点数到f并返回流的引用。

    QDataStream & QDataStream::operator>> ( char *& s )

    这是一个重载成员函数,提供了方便。它的行为基本上和上面的函数相同。

    从流中读取一个以“/0”结尾的字符串到s并返回流的引用。

    存放这个字符串的空间是使用new来分配的——调用者必须使用delete[]来销毁它。

    QDataStream & QDataStream::readBytes ( char *& s, uint & l )

    从流中读取缓存s并返回流的引用。

    这个缓存s是使用new来分配的。需要使用delete[]来销毁它。如果长度为0或者s没能被分配,s就被设置为0。

    l参数将被设置为缓存的长度。

    串行化格式首先是一个Q_UINT32长度的说明符,然后是l字节的数据。注意数据不是编码的。

    也可以参考readRawBytes()和writeBytes()。

    QDataStream & QDataStream::readRawBytes ( char * s, uint len )

    从流中读取len字节到s并返回流的引用。

    这个缓存s必须被预先分配。数据不是编码的。

    也可以参考readBytes()、QIODevice::readBlock()和writeRawBytes()。

    两个函数的区别:

    readBytes函数的形参不必自己申请空间,函数内部会new出一个空间(注意形参是一个指针的引用),并且这个函数我估计会读出流的所有,并把读出的字符长度赋给l。

    而readRawBytes函数则需要先申请一段空间,并指定好读出的字符长度len。

    ps:之前误认为用readBytes函数要先自己申请一段空间给s,每次readBytes前我都申请一段空间,程序跑起来内存升的厉害,终于发现了这个问题。

    void QDataStream::setByteOrder ( int bo )

    设置串行化字节顺序为bo

    bo参数可以是QDataStream::BigEndian或QDataStream::LittleEndian。

    默认设置是高字节在前。我们强烈建议你保留这个设置,除非你有特殊需要。

    也可以参考byteOrder()。

    void QDataStream::setDevice ( QIODevice * d )

    设置IO设备为d

    也可以参考device()和unsetDevice()。

    void QDataStream::setPrintableData ( bool enable )

    设置(如果enable为真)或者清空可打印数据标记。

    如果这个标记被设置,写函数将生成由可打印字符(7位ASCII码)的输出。

    我们建议只有在调试的情况下打开可打印数据设置(它比较慢并且生成了更多的输出)。

    void QDataStream::setVersion ( int v )

    设置数据串行化格式的版本号。

    如果你只使用当前版本的Qt,你不需要设置这个版本号。

    为了提供新的功能,在一些Qt的版本中,一些Qt类的数据流串行化格式变化了。如果你想读较早版本Qt中创建的数据,或者写可供较早版本Qt编译的程序能够读的数据,请使用这个函数来设置QDataStream的串行化格式。

    • 为了兼容Qt 3.0,请使用v == 4。
    • 为了兼容Qt 2.1.x和Qt 2.2.x,请使用v == 3。
    • 为了兼容Qt 2.0.x,请使用v == 2。
    • 为了兼容Qt 1.x,请使用v == 1。

    也可以参考version().

    void QDataStream::unsetDevice ()

    清除IO设备。这个和调用setDevice( 0 )一样。

    也可以参考device()和setDevice()。

    int QDataStream::version () const

    返回数据串行化格式的版本号。 在Qt 3.0中,这个版本号为4。

    也可以参考setVersion()。

    QDataStream & QDataStream::writeBytes ( const char * s, uint len )

    写长度说明符len和缓存s到流中并返回流的引用。

    len被串行化为一个Q_UINT32,接着的是s中的len字节。注意数据不是编码的。

    也可以参考writeRawBytes()和readBytes()。

    QDataStream & QDataStream::writeRawBytes ( const char * s, uint len )

    s中写len字节到流中并且返回流的引用。数据不是编码的。

    也可以参考writeBytes()、QIODevice::writeBlock()和readRawBytes()。

    http://blog.sina.com.cn/s/blog_a401a1ea0101fgvj.html

    QT 读取二进制文件 例子

    DataStream.h

    C++代码 复制代码 收藏代码
    1. #ifndef DATASTREAM_H
    2. #define DATASTREAM_H
    3. #include
    4. #include
    5. class A{
    6. private:
    7. int a1;
    8. QString a2;
    9. public:
    10. A(){
    11. a1 = 0;
    12. a2 = QString();
    13. }
    14. A(int v1,QString v2){
    15. a1 = v1;
    16. a2 = v2;
    17. }
    18. int getA1()const{
    19. return a1;
    20. }
    21. QString getA2()const{
    22. return a2;
    23. }
    24. };
    25. QDataStream& operator<<(QDataStream& out,const A& a);
    26. QDataStream& operator>>(QDataStream& in,A& a);
    27. #endif // DATASTREAM_H



    DataStream.cpp

    C++代码 复制代码 收藏代码
      1. #include "DataStream.h"
      2. #include
      3. #include
      4. using namespace std;
      5. QDataStream& operator<<(QDataStream& out,const A& a){
      6. int a1 = a.getA1();
      7. QString a2 = a.getA2();
      8. out << a1;
      9. out << a2;
      10. return out;
      11. }
      12. QDataStream& operator>>(QDataStream& in,A& a){
      13. int a1;
      14. QString a2;
      15. in >> a1;
      16. in >> a2;
      17. a = A(a1,a2);
      18. return in;
      19. }
      20. int main(){
      21. A a(10,"abc");
      22. QString fileName = "test.dat";
      23. QFile writeFile(fileName);
      24. writeFile.open(QIODevice::WriteOnly);
      25. QDataStream out(&writeFile);
      26. out << a;
      27. writeFile.close();
      28. QFile readFile(fileName);
      29. readFile.open(QIODevice::ReadOnly);
      30. QDataStream in(&readFile);
      31. A a2;
      32. in >> a2;
      33. readFile.close();
      34. cout << "a1:" << a2.getA1() << ",a2:" << a2.getA2().toStdString() << endl;
      35. }
      36. a1:10,a2:abc

    http://blog.sina.com.cn/s/blog_a401a1ea0101fgs1.html

  • 相关阅读:
    SandBoxieLPC通信
    process map
    分块/分块除法
    (分块除法,题目数学式子的提取,%的除法转化和%的取余数的应用)
    并发编程四(1) 线程同步 生产者消费者
    vue系列 箭头函数和this
    并发编程四(3) 线程同步 Event信号传递
    金融支付财务
    2.Vue系列 基础语法
    安全测试工具
  • 原文地址:https://www.cnblogs.com/findumars/p/5712990.html
Copyright © 2020-2023  润新知