Qt5.11开发文档翻译: QDataStream 类 ,QDataStream Class
QDataStream 类,提供了此功能:将二进制数据序列化到某个 QIODevice 中。 详细说明……
头文件: |
#include <QDataStream> |
qmake指令: |
QT += core |
注意 : 这个类中的所有函数都是 可重入的 。
QDataStream 类,提供了此功能:将二进制数据序列化到某个 QIODevice 中。
一个数据流,是指一个二进制流,其中包含着编码后的信息。这些信息100%地与主机电脑的操作系统、中央处理器及字节序无关。
妳也可以使用数据流来对 原始 的未编码二进制数据 进行读写。如果妳想要使用一个具有“解析”能力的输入流,那么参考 QTextStream 。
QDataStream 类,实现了对于C++的基本数据类型的序列化支持,例如 char 、 short 、 int 、 char * 等等。对于更复杂的数据类型的序列化,则是通过将数据分解成基本单元来实现的。
数据流,与 QIODevice 紧密合作。 QIODevice ,代表着某个输入/输出介质,程序可在该介质上读取数据及写入数据。 QFile 类,即是输入/输出设备的一个例子。
示例(向流中写入二进制数据):
QFile file("file.dat");
file.open( QIODevice ::WriteOnly);
QDataStream out(&file); // 我们会将数据序列化到文件(file)中去
out << QString ("the answer is"); // 序列 化一个字符串
out << ( qint32 )42; // 序列 化一个整数
示例(从流中读取二进制数据):
QFile file("file.dat");
file.open( QIODevice ::ReadOnly);
QDataStream in(&file); // 从文件(file)中读取之前序列化的数据
QString str;
qint32 a;
in >> str >> a; // 读 取 到 "the answer is" 和 42
向流中写入的每个条目,都是以一种预先定义的与该条目的类型相关的二进制格式来写入的。预先支持的Qt类型包括:QBrush 、 QColor 、 QDateTime 、 QFont 、 QPixmap 、 QString 、 QVariant 及狠多其它类型。如想了解所有支持数据流的Qt类型的完整列表,则阅读 将 Qt数据类型序列 化 。
对于整数,最好的处理方式是,在写入时,将它们转换成某个Qt整数类型,而在读取时,也使用相同的Qt整数类型。这样能够确保妳能够得到正确尺寸的整数,并且能够为妳隔离掉编译器和平台的差异。
举个例子,对于一个 char *字符 串,其写入方式是,首先写入一个32位的整数,其值等于该字符串包括末尾'\0'字节的长度,然后写入该字符串的所有字符,包括末尾的'\0'字节。在读取 char *字符串 时,首先读取4个字节,以获取一个32位的长度值,然后读取那么多个字符,以组成这个 char *字符串 ,包括末尾的'\0'字节终止符也会被读入。
最初的输入/输出设备,通常是在构造函数中设置的,不过也可以通过 setDevice ()来改变。如果读取到达了数据的末尾(或者,尚未设置输入/输出设备),则 atEnd ()会返回真(true)。
QDataStream 的二进制格式,从Qt 1.0开始就一直在演化,并且,极有可能随着Qt 日后的改变而继续演化。在读取或写入复杂类型时,有一点狠重要,那就是,要确保,在读取及写入时要使用相同版本( version ())的流。如果妳想要保持前向及后向兼容性,那么,可以在程序中将版本号硬编码写入:
stream .setVersion( QDataStream ::Qt_4_0);
如果妳在创造一种新的二进制数据格式,比如说为妳所创造的程序设计一种文件格式,那么,妳就可以利用 QDataStream 来以一种可移植的格式写入数据。一般情况下,妳需要写入一个简短的文件头,其中包含一个版本号,以使得妳在日后能够对该格式进行扩展。例如:
QFile file("file.xxx");
file.open( QIODevice ::WriteOnly);
QDataStream out(&file);
// 写入 一个文件头,其中包含一个“魔数”和一个版本号
out << ( quint32 )0xA0B0C0D0;
out << ( qint32 )123;
out.setVersion( QDataStream ::Qt_4_0);
// 写入数据
out << lots_of_interesting_data;
日后,这样读取:
QFile file("file.xxx");
file.open( QIODevice ::ReadOnly);
QDataStream in(&file);
// 读取 并检查文件头
quint32 magic;
in >> magic;
if (magic != 0xA0B0C0D0)
return XXX_BAD_FILE_FORMAT;
// 读取版本 号
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);
// 读取数据
in >> lots_of_interesting_data;
if (version >= 120)
in >> data_new_in_XXX_version_1_2;
in >> other_interesting_data;
妳可以选择,在序列化数据时,使用何种字节序。默认设置是,大端在前(最重要的字节(MSB)在最前面)。将这个选项设置成小端在前的话,会打破可移植性(除非读取的一方也改变成小端在前)。我们建议保持这个默认设置不变,除非妳确实有特殊的需求。
妳可以想要直接从数据流中读取/写入妳自己的原始二进制数据。可使用 readRawData ()来从流中将数据读取到一个预先分配好空间的 char * 中去。类似地,可使用 writeRawData ()来向流中写入数据。注意,对于数据的任何编码/解码都必须由妳自己完成。
类似的一对函数是 readBytes ()和 writeBytes ()。这两个函数,与相应的原始( raw )版本不同: readBytes ()会先读入一个quint32,这个值会被用来作为要读取的数据的长度值,然后会读取那么多个字节的数据,放入到预先分配空间的 char * 中去; writeBytes ()会先写入一个quint32,用来 表示数据的长度,然后再写入数据本身。注意,对于数据(除了那个表示长度的quint32 整数之外)本身的编码/解码,必须由妳自己来进行。
Qt中的那些容器类,也可以被序列化到 QDataStream 中去。这包括: QList 、 QLinkedList 、 QVector 、 QSet 、 QHash 和 QMap 。对应的流式操作符,被声明为那些类的非成员函数。
除了此处说明的那些重载的流式操作符之外,任何一个妳想要序列化到 QDataStream 中去的Qt 类,都会具有对应的流式操作符,被声明为该类的非成员函数:
QDataStream &operator<<( QDataStream &, const QXxx &);
QDataStream &operator>>( QDataStream &, QXxx &);
例如,此处展示的是,被声明为 QImage 类的非成员函数的流式操作符:
QDataStream & operator<< ( QDataStream & stream, const QImage & image);
QDataStream & operator>> ( QDataStream & stream, QImage & image);
要想确认妳最喜爱的Qt 类是否定义有类似的流式操作符的话,则查看那个类的文档中的 相关非成员函数 小节。
在使用数据流来对某个异步设备进行操作时,对应的数据块可能在任何时间点到来。 QDataStream 类实现了一种事务机制,它提供了这种能力:使用一系列的流操作来原子式地读取数据。例如,妳可以在一个连接到readyRead()信号的槽中使用事务来处理来自套接字的不完整数据读取:
in .startTransaction();
QString str;
qint32 a;
in >> str >> a; // 尝试原子 式地读取数据包
if (!in.commitTransaction())
return; // 等待更多数据
如果没有收到完整的数据包,那么,这砣代码会将流恢复到它的初始位置,然后,妳就需要等待更多数据的到来。
参考 QTextStream 和 QVariant 。
用于读取/写入数据的字节序。
常量 |
值 |
说明 |
QDataStream::BigEndian |
QSysInfo::BigEndian |
最重要的字节在最前(默认值) |
QDataStream::LittleEndian |
QSysInfo::LittleEndian |
最不重要的字节在最前 |
enum QDataStream:: FloatingPointPrecision
在读取/写入数据时使用的浮点数精度。只有当数据流的版本大于或等于 Qt_4_6 时才有效。
警告:对于分别写入和读取该数据流的两个对象,其使用的浮点数精度必须是相同值。
常量 |
值 |
说明 |
QDataStream::SinglePrecision |
0 |
这个数据流中的所有浮点数都具有32位精度。 |
QDataStream::DoublePrecision |
1 |
这个数据流中的所有浮点数都具有64位精度。 |
参考 setFloatingPointPrecision ()和 floatingPointPrecision ()。
这个枚举,描述了数据流当前的状态。
常量 |
值 |
说明 |
QDataStream::Ok |
0 |
这个数据流当前工作正常。 |
QDataStream::ReadPastEnd |
1 |
这个数据流在读取过程中已经越过了底层设备的数据末尾了。 |
QDataStream::ReadCorruptData |
2 |
这个数据流读取到了破损的数据。 |
QDataStream::WriteFailed |
3 |
这个数据流无法向底层设备写入数据。 |
这个枚举,提供了对于历史上的数据序列化格式版本号的符号简写。
常量 |
值 |
说明 |
QDataStream::Qt_1_0 |
1 |
版本1 (Qt 1.x) |
QDataStream::Qt_2_0 |
2 |
版本2 (Qt 2.0) |
QDataStream::Qt_2_1 |
3 |
版本3 (Qt 2.1、2.2、2.3) |
QDataStream::Qt_3_0 |
4 |
版本4 (Qt 3.0) |
QDataStream::Qt_3_1 |
5 |
版本5 (Qt 3.1、3.2) |
QDataStream::Qt_3_3 |
6 |
版本6 (Qt 3.3) |
QDataStream::Qt_4_0 |
7 |
版本7 (Qt 4.0、Qt 4.1) |
QDataStream::Qt_4_1 |
Qt_4_0 |
版本7 (Qt 4.0、Qt 4.1) |
QDataStream::Qt_4_2 |
8 |
版本8 (Qt 4.2) |
QDataStream::Qt_4_3 |
9 |
版本9 (Qt 4.3) |
QDataStream::Qt_4_4 |
10 |
版本10 (Qt 4.4) |
QDataStream::Qt_4_5 |
11 |
版本11 (Qt 4.5) |
QDataStream::Qt_4_6 |
12 |
版本12 (Qt 4.6、Qt 4.7、Qt 4.8) |
QDataStream::Qt_4_7 |
Qt_4_6 |
与Qt_4_6相同。 |
QDataStream::Qt_4_8 |
Qt_4_7 |
与Qt_4_6相同。 |
QDataStream::Qt_4_9 |
Qt_4_8 |
与Qt_4_6相同。 |
QDataStream::Qt_5_0 |
13 |
版本13 (Qt 5.0) |
QDataStream::Qt_5_1 |
14 |
版本14 (Qt 5.1) |
QDataStream::Qt_5_2 |
15 |
版本15 (Qt 5.2) |
QDataStream::Qt_5_3 |
Qt_5_2 |
与Qt_5_2相同 |
QDataStream::Qt_5_4 |
16 |
版本16 (Qt 5.4) |
QDataStream::Qt_5_5 |
Qt_5_4 |
与Qt_5_4相同 |
QDataStream::Qt_5_6 |
17 |
版本17 (Qt 5.6) |
QDataStream::Qt_5_7 |
Qt_5_6 |
与Qt_5_6相同 |
QDataStream::Qt_5_8 |
Qt_5_7 |
与Qt_5_6相同 |
QDataStream::Qt_5_9 |
Qt_5_8 |
与Qt_5_6相同 |
QDataStream::Qt_5_10 |
Qt_5_9 |
与Qt_5_6相同 |
QDataStream::Qt_5_11 |
Qt_5_10 |
与Qt_5_6相同 |
参考 setVersion ()和 version ()。
void QDataStream:: abortTransaction ()
放弃一次读取事务。
这个函数,用于在高层协议出错或者流同步出错时丢弃事务。
如果是在某个内层事务上调用这个方法,则会导致事务的放弃行为被向上传递到最外层的事务上去,并且,后续启动的内层事务会被强制失败。
对于最外层的事务,会丢弃掉恢复点以及内部为该个流复制的任何数据。不会影响到流的当前读取位置。
会将数据流的状态设置成
常量 |
说明 |
ReadCorruptData |
。 |
这个函数是从Qt 5.7 开始引入的。
参考 startTransaction ()、 commitTransaction ()和 rollbackTransaction ()。
QDataStream::ByteOrder QDataStream:: byteOrder () const
返回当前设置的字节序 -- 其值是 BigEndian 或 LittleEndian 。
参考 setByteOrder ()。
bool QDataStream:: commitTransaction ()
完成一个读取事务。如果在该事务过程中未发生任何错误,则返回真( true );否则返回假( false )。
如果是在某个内层事务上调用这个方法,那么,提交动作会被后延,直到在最外层的事务上调用了commitTransaction()、 rollbackTransaction ()或 abortTransaction ()为止。
否则,如果流的状态表明读取动作已经越过了数据的末尾,那么,这个函数会将流的数据恢复到发起 startTransaction ()调用时的位置。如果发生了这种情况,那么,妳就需要等待更多数据的到来,然后再启动一个新的事务。如果数据流读取到了破损的数据,或者任何一个内层事务被放弃了,那么,这个函数会放弃掉事务。
这个函数是从Qt 5.7 开始引入的。
参考 startTransaction ()、 rollbackTransaction ()和 abortTransaction ()。
QDataStream::FloatingPointPrecision QDataStream:: floatingPointPrecision () const
返回这个数据流的浮点数精度。
这个函数是从Qt 4.6 开始引入的。
参考 FloatingPointPrecision 和 setFloatingPointPrecision ()。
QDataStream &QDataStream:: readBytes ( char *& s , uint & l )
从流中读取内容到缓冲区 s ,并且返回这个流的引用。
此处的缓冲区 s ,是使用 new [] 来分配空间的。日后,妳需要使用 delete [] 操作符来销毁它。
l参数,会被设置成缓冲区的长度。如果读取的字符串是空白的,那么 l 会被设置成0,并且 s 会被设置成空指针。
具体的序列化格式是,一个quint32的长度值,然后是 l 个字节的数据。
参考 readRawData ()和 writeBytes ()。
int QDataStream:: readRawData ( char * s , int len )
从流中向 s 中读取最多 len 个字节的数据,并且返回实际读取的字节数。如果发生了错误,那么这个函数会返回-1。
缓冲区 s 必须预先分配空间。数据 并未 被编码。
参考 readBytes ()、 QIODevice::read ()和 writeRawData ()。
void QDataStream:: rollbackTransaction ()
将某个读取事务还原。
这个函数,通常用于,在提交事务之前,如果检测到发生了不完整的读取操作,则对事务进行回滚。
如果在某个内层事务上调用这个函数,那么,还原动作会一直传播到最外层的事务,并且,后续启动的内层事务会强制失败。
对于最外层的事务,会将流中的数据恢复到发生 startTransaction ()调用时的位置。如果在数据流中已经读取到了破损的数据,或者,任何一个内层事务被放弃了,那么,这个函数会放弃掉该事务。
如果之前的流操作是成功了,那么,会将数据流的状态设置成
常量 |
说明 |
ReadPastEnd |
。 |
这个函数是从Qt 5.7 开始引入的。
参考 startTransaction ()、 commitTransaction ()和 abortTransaction ()。
void QDataStream:: setByteOrder ( QDataStream::ByteOrder bo )
将序列化的字节序设置为 bo 。
此处的 bo参数,可以是 QDataStream::BigEndian 或 QDataStream::LittleEndian 。
默认设置是大端在前。我们建议不要改动这个选项,除非妳确实有特殊的需求。
参考 byteOrder ()。
void QDataStream:: setFloatingPointPrecision ( QDataStream::FloatingPointPrecision precision )
将这个数据流的浮点数精度设置成 precision 。如果浮点数精度是 DoublePrecision ,并且数据流的版本号是 Qt_4_6 或更高,那么,所有的浮点数,在写入和读取时,都会使用64 位的精度。如果浮点数精度是 SinglePrecision ,并且数据流的版本号是 Qt_4_6 或更高,那么,所有的浮点数,在写入和读取时,都会使用32 位的精度。
对于 Qt_4_6 之前的版本,数据流中所使用的浮点数的精度,取决于具体调用的流操作符。
默认值是 DoublePrecision 。
注意,这个属性,并不会影响到对于 qfloat16 实例的序列化和反序列化。
警告: 这个属性,对于用于写入和读取该个数据流的对象,都必须设置成相同的值。
这个函数是从Qt 4.6 开始引入的。
参考 floatingPointPrecision ()。
void QDataStream:: setVersion ( int v )
将数据序列化格式的版本号设置成 v ,它是 Version 枚举中的一个值。
如果妳正在使用的是 Qt 的当前版本,那么,妳并不是 必须 设置版本号,然而,对于妳自定义的二进 制格式,我们建议妳要设置版本号;参考详细说明中的 版本 号 。
为了支持新的功能,在某些Qt 版本中,某些Qt 类的数据流序列化格式会发生变化。如果妳想要读取由较旧版本的Qt 创建的数据,或者,想写入能够被那些与较旧版本的Qt 编译到一起的程序读取的数据,那么,就应当使用这个函数来修改 QDataStream 所使用的序列化格式。
Version 枚举,提供了针对不同版本的Qt 所使用的符号常量。例如:
QDataStream out(file);
out.setVersion( QDataStream ::Qt_4_0);
int QDataStream:: skipRawData ( int len )
从设备中跳过 len 个字节的数据。返回实际跳过的字节个数,如果出错,则返回-1。
这个函数,等价于,针对某个长度为 len 的缓冲区调用 readRawData (),并且忽略掉该个缓冲区。
这个函数是从Qt 4.1 开始引入的。
参考 QIODevice::seek ()。
void QDataStream:: startTransaction ()
在这个流上启动一个新的读取事务。
在读取操作中,定义一个可恢复的位置。对于串行设备,读取到的数据会在内部进行复制,以便在发生不完整读取时进行恢复。对于随机访问设备,这个函数会记录流中的当前位置。调用 commitTransaction ()、 rollbackTransaction ()或 abortTransaction ()来结束当前事务。
一旦启动了某个事务,后续再调用这个函数的话,会使得该个事务成为递归的。内层事务会充当最外层事务的代理(也就是说,向最外层事务报告读取操作的状态,使得最外层事务能够恢复流的位置)。
注意 : 不支持恢复到由嵌套的startTransaction()调用所记录的位置。
如果在某个事务中发生了错误(包括内层事务失败),那么,从该个数据流中读取数据的操作会被制止(后续的读取操作都会返回空白/零值),并且,后续的内层事务会被强制失败。再启动一个新的最外层 事务,就会从这种状态下恢复。这种行为,使得,不需要单独为每次读取操作进行错误检查。
这个函数是从Qt 5.7 开始引入的。
参考 commitTransaction ()、 rollbackTransaction ()和 abortTransaction ()。
QDataStream::Status QDataStream:: status () const
返回数据流的状态。
参考 Status 、 setStatus ()和 resetStatus ()。
int QDataStream:: version () const
返回当前的数据序列化格式的版本号码。
参考 setVersion ()和 Version 。
QDataStream &QDataStream:: writeBytes (const char * s , uint len )
将长度值 len 和缓冲区 s 的内容写入到流中,并且返回这个流的引用。
len 会被序列化为一个quint32,其后是来自于 s 的 len 个字节。注意,数据并 不会 被编码。
参考 writeRawData ()和 readBytes ()。
int QDataStream:: writeRawData (const char * s , int len )
将 s 中的 len 个字节数据写入到流中。返回实际写入的字节数,如果出错,则返回-1。数据并 不会 被编码。
参考 writeBytes ()、 QIODevice::write ()和 readRawData ()。
未知美人
未知美人
Your opinionsHxLauncher: Launch Android applications by voice commands