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

QDataStream类参考(串行化数据,可设置低位高位,以及版本号),还有一个例子的更多相关文章

  1. Qt串行化的输入和输出(使用QDataStream读写QByteArray,对QIODevice直接起作用)

    参考https://lug.ustc.edu.cn/sites/qtguide/ 今天看了一个介绍Qt串行化的介绍,感觉很受益,就记录了下来. 串行化(Serialization)是计算机科学中的一个 ...

  2. VC++ chap13 文档与串行化

    Lesson 13 文档与串行化 13.1使用CArchive类对文件进行读写操作 //让对象数据持久性的过程称之为串行化,或者序列化 void CGraphicView::OnFileWrite() ...

  3. JavaEE 对象的串行化(Serialization)

    什么情况下需要序列化 a)当你想把的内存中的对象写入到硬盘的时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候:再稍微解释一下:a)比如说你的内存不够用了,那计算机就要 ...

  4. MFC文件IO和串行化

    一. MFC中CFile对象实现了磁盘文档的读写,但是大部分MFC应用程序的IO服务都使用CArchive对象来完成.不管CFile和Archive输入输出的都是二进制数据,非文本数据. int a ...

  5. MFC用串行化实现文档存储和读取功能

    在面向对象的程序设计中,一般都是用二进制文件来保存文档资料.在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件:利用串行化存取文件.其中用CFil ...

  6. MFC【6】文件I/O和串行化

    文件输入和输出(I/O)服务是所有操作系统的主要工作.Microsoft Windows提供了各种API函数用来读.写和操作磁盘文件.MFC将这些桉树和CFile类融合在面对对象的模型里.其中CFil ...

  7. [Python]ctypes+struct实现类c的结构化数据串行处理

    1. 用C/C++实现的结构化数据处理 在涉及到比较底层的通信协议开发过程中, 往往需要开发语言能够有效的表达和处理所定义的通信协议的数据结构. 在这方面是C/C++语言是具有天然优势的: 通过str ...

  8. MFC如何生成一个可串行化的类

    一.MFC允许对象在程序运行的整个过程中持久化的串行化机制 (1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程. (2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构 ...

  9. VC++ MFC如何生成一个可串行化的类

    一.MFC允许对象在程序运行的整个过程中持久化的串行化机制(1)串行化是指向持久化存储媒介(如一个磁盘文件)读或写对象的过程.(2)串行化用于在程序运行过程时或之后修复结构化数据(如C++类或结构)的 ...

随机推荐

  1. Qt构建工具QBS之零 —— QBS 概览

    本系列文章起因 自己非常喜欢 QT 这个框架, 使用 QT 这几年, IDE 一直是使用的 QT 自带的 Qt Creator, 这个 IDE 本身比较轻巧, 同事相关的语法提示之类的也算够用, 但是 ...

  2. 改进RazorPad

    从Git 上下载了作者的源码后,感觉用起来挺别扭,而且还要BUG............ 经过“篡改”后,好用多了,呵呵..

  3. AIX和Linux中wtmp的不同处理方式

    wtmp 记录用户登录和退出事件.它和utmp日志文件相似,但它随着登陆次数的增加,它会变的越来越大,有些系统的ftp访问也在这个文件里记录,同时它也记录正常的系统退出时间,可以用ac和last命令访 ...

  4. bzoj 1191

    http://www.lydsy.com/JudgeOnline/problem.php?id=1191 二分+二分图匹配. 首先二分可以答对前mid道题,然后做二分图. 左边是题目,右边是锦囊. 做 ...

  5. hdu5014:number sequence对称思想

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5014 题目大意:给定数组 a[]={0,1,2......n} 求一个数组b[] 元素也为0.... ...

  6. python filecmp标准库基础学习

    # -*- coding: utf-8 -*-# 作者:新手__author__ = 'Administrator'#文件的比较import os,filecmp#作用用于比较系统中的目录和文件#例子 ...

  7. Makefile学习(三)执行make

    9 执行make 一般方法:make. 某些情况:1.可能需要使用make更新一部分过时文件而不是全部 2.需要使用另外的编译器或者重新定义编译选项 3.只需要查看哪些文件被修改,不需要重新编译 所以 ...

  8. Html与css基础

    1.html的定义 (1).html:超文本标记语言(HyperText Markup Language),它主要包括"头"(Head)和"主体"(Body)两 ...

  9. 工程与科学数值方法的Matlab实现

    %stats.m function [mean,stdev]=stats(x) n=length(x);mean=sum(x)/n;stdev=sqrt(sum((x-mean).^2/(n-1))) ...

  10. 不指定order by时Sql的排序

    在sql中不指定Order by,排序是按照主键吗?答案是不一定.举个例子:   查询AttendanceEmpRank表,主键是AttendanceEmployeeRankId,而且是聚集索引   ...