QDataStream
本文来自:
智谱清言
Qt助手
------
QDataStream
是 Qt 框架中的一个类,用于序列化和反序列化二进制数据。它允许你将基本数据类型(如 int
、double
、QString
等)以及 Qt 容器类(如 QList
、QMap
等)写入到一个数据流中,或者从数据流中读取这些数据。
------
以下是 QDataStream
的一些关键特性:
主要功能
- 序列化:将数据结构转换成字节流的过程。
- 反序列化:从字节流中恢复数据结构的过程。
------
常用的函数类似如下格式:
QDataStream &operator<<(QDataStream &out, T &data)
:将数据data
写入到数据流out
中。QDataStream &operator>>(QDataStream &in, T &data)
:从数据流in
中读取数据到data
。
------
使用示例
写入数据
#include <QDataStream>
#include <QFile>
#include <QString>
int main() {
QFile file("example.dat");
if (!file.open(QIODevice::WriteOnly)) {
return -1;
}
QDataStream out(&file);
out.setVersion(QDataStream::Qt_5_0);
QString str = "Hello, World!";
out << str;
file.close();
return 0;
}
在这个例子中,我们创建了一个名为 example.dat
的文件,并使用 QDataStream
将一个 QString
写入到文件中。
------
读取数据
#include <QDataStream>
#include <QFile>
#include <QString>
int main() {
QFile file("example.dat");
if (!file.open(QIODevice::ReadOnly)) {
return -1;
}
QDataStream in(&file);
in.setVersion(QDataStream::Qt_5_0);
QString str;
in >> str;
file.close();
return 0;
}
在这个例子中,我们从example.dat文件中读取一个QString。
---------
注意事项
- 版本控制:在序列化和反序列化数据时,应该指定
QDataStream
的版本,以确保数据的兼容性。通常使用setVersion()
方法来设置版本号。 - 错误处理:在使用
QDataStream
时,应该检查数据流的状态,以确保数据正确地写入或读取。 - 字节顺序:
QDataStream
默认使用大端字节序,但你可以使用setByteOrder()
方法来改变字节顺序。
QDataStream
非常适合于在文件、网络或其他二进制数据流中传输和存储复杂的数据结构。它是 Qt 框架中处理二进制数据的一个强大工具。
---------
在 Qt 框架中,QDataStream
类使用一个枚举类型 Version
来指定数据流的版本。这个枚举类型包含了不同的版本号,每个版本号对应于特定的 Qt 版本。
以下是 QDataStream::Version
枚举类型的成员及其对应的信息:
QDataStream::Qt_1_0
:对应于 Qt 1.0 版本。QDataStream::Qt_2_0
:对应于 Qt 2.0 版本。QDataStream::Qt_3_0
:对应于 Qt 3.0 版本。QDataStream::Qt_4_0
:对应于 Qt 4.0 版本。QDataStream::Qt_4_1
:对应于 Qt 4.1 版本。QDataStream::Qt_4_2
:对应于 Qt 4.2 版本。QDataStream::Qt_4_3
:对应于 Qt 4.3 版本。QDataStream::Qt_4_4
:对应于 Qt 4.4 版本。QDataStream::Qt_4_5
:对应于 Qt 4.5 版本。QDataStream::Qt_4_6
:对应于 Qt 4.6 版本。QDataStream::Qt_4_7
:对应于 Qt 4.7 版本。QDataStream::Qt_4_8
:对应于 Qt 4.8 版本。QDataStream::Qt_4_9
:对应于 Qt 4.9 版本。QDataStream::Qt_5_0
:对应于 Qt 5.0 版本。QDataStream::Qt_5_1
:对应于 Qt 5.1 版本。QDataStream::Qt_5_2
:对应于 Qt 5.2 版本。QDataStream::Qt_5_3
:对应于 Qt 5.3 版本。QDataStream::Qt_5_4
:对应于 Qt 5.4 版本。QDataStream::Qt_5_5
:对应于 Qt 5.5 版本。QDataStream::Qt_5_6
:对应于 Qt 5.6 版本。QDataStream::Qt_5_7
:对应于 Qt 5.7 版本。QDataStream::Qt_5_8
:对应于 Qt 5.8 版本。QDataStream::Qt_5_9
:对应于 Qt 5.9 版本。- ......
------
void QDataStream::setVersion(int v)
在 Qt 框架中,QDataStream
类提供了一个成员函数 setVersion(int v)
,用于设置数据流的版本。这个函数允许你指定 QDataStream
应该使用的版本号,以确保序列化和反序列化操作的兼容性。
以下是 setVersion(int v)
函数的详细信息:
-
功能:该函数用于设置
QDataStream
的版本号。这个版本号用于确保数据流的序列化和反序列化操作能够正确处理数据,特别是在处理不同版本的 Qt 库时。 -
参数:
v
:一个整数,表示QDataStream
应该使用的版本号。这个版本号应该是一个枚举QDataStream::Version
的值。
-
返回值:无返回值。
-
使用场景:当你在处理不同版本的 Qt 库之间的数据传输时,或者当你想要确保数据流与特定的 Qt 版本兼容时,你应该调用这个函数。
-
注意事项:确保传递给
setVersion()
的版本号是有效的,即它应该是一个QDataStream::Version
枚举类型的值。不正确的版本号可能会导致数据序列化和反序列化过程中的错误。
以下是如何使用 setVersion()
的一个示例:
#include <QDataStream>
int main() {
// 假设我们要序列化和反序列化数据,并确保它们与 Qt 5.10 版本兼容
QDataStream dataStream;
dataStream.setVersion(QDataStream::Qt_5_10);
// 序列化数据
// ...
// 反序列化数据
// ...
return 0;
}
在这个例子中,我们创建了一个 QDataStream
对象,并将其版本设置为与 Qt 5.10 兼容。这样,当我们序列化和反序列化数据时,我们就可以确保它们在不同的 Qt 版本之间是兼容的。
------
void QDataStream::setVersion(int v)
Sets the version number of the data serialization format to v, a value of the Version enum.
serialization:序列化;串行化;
You don't have to set a version if you are using the current version of Qt, but for your own custom binary formats we recommend that you do; see Versioning in the Detailed Description.
To accommodate new functionality, the datastream serialization format of some Qt classes has changed in some versions of Qt.
accommodate:顺应,适应;
functionality:功能
If you want to read data that was created by an earlier version of Qt, or write data that can be read by a program that was compiled with an earlier version of Qt, use this function to modify the serialization format used by QDataStream.
The Version enum provides symbolic constants for the different versions of Qt. For example:
symbolic:符号的,使用象征的
constants:常量
QDataStream out(file);
out.setVersion(QDataStream::Qt_4_0);
---------
Versioning
QDataStream's binary format has evolved since Qt 1.0, and is likely to continue evolving to reflect changes done in Qt.
evolve:逐步发展,逐渐演变
reflect:反映,显示,表明;
When inputting or outputting complex types, it's very important to make sure that the same version of the stream (version()) is used for reading and writing. If you need both forward and backward compatibility, you can hardcode the version number in the application:
forward and backward compatibility:前后兼容
stream.setVersion(QDataStream::Qt_4_0);
If you are producing a new binary data format, such as a file format for documents created by your application, you could use a QDataStream to write the data in a portable format.
portable:可移植的
magic:幻数
expansion:扩展
Typically, you would write a brief header containing a magic string and a version number to give yourself room for future expansion. For example:
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;
Then read it in with:
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;
You can select which byte order to use when serializing data.
The default setting is big endian (MSB first). Changing it to little endian breaks the portability (unless the reader also changes to little endian). We recommend keeping this setting unless you have special requirements.
---------
Reading and Writing Raw Binary Data
You may wish to read/write your own raw binary data to/from the data stream directly. Data may be read from the stream into a preallocated char * using readRawData().
preallocated:被预先分配的
Similarly data can be written to the stream using writeRawData(). Note that any encoding/decoding of the data must be done by you.
A similar pair of functions is readBytes() and writeBytes().
counterparts:同行
as follows:如下所述
These differ from their raw counterparts as follows: readBytes() reads a quint32 which is taken to be the length of the data to be read, then that number of bytes is read into the preallocated char *; writeBytes() writes a quint32 containing the length of the data, followed by the data. Note that any encoding/decoding of the data (apart from the length quint32) must be done by you.
------
Reading and Writing Qt Collection Classes
The Qt container classes can also be serialized to a QDataStream. These include QList, QLinkedList, QVector, QSet, QHash, and QMap. The stream operators are declared as non-members of the classes.
------
Reading and Writing Other Qt Classes
In addition to the overloaded stream operators documented here, any Qt classes that you might want to serialize to a QDataStream will have appropriate stream operators declared as non-member of the class:
appropriate:合适的
QDataStream &operator<<(QDataStream &, const QXxx &);
QDataStream &operator>>(QDataStream &, QXxx &);
For example, here are the stream operators declared as non-members of the QImage class:
QDataStream & operator<< (QDataStream& stream, const QImage& image);
QDataStream & operator>> (QDataStream& stream, QImage& image);
To see if your favorite Qt class has similar stream operators defined, check the Related Non-Members section of the class's documentation page.