QTextStream能方便的操作人类可读的文本,如字符串,整数等。但对于如图片( QPixmap)、字体(QFont)等这些无法保存为普通文本的类型,它就无能为力了,即使勉强保存了它们,也将会破坏原有的文件或数据结构,这是我们不希望看到的。
于是,Qt提供了一个方便的类QDataStream,让我们能便捷的操纵它们的二进制数据,使数据序列化。保持数据的完整性。点些查看它所支持的数据类型。
可以看到,它支持的类型是极多的。在网络传输数据部分,这个类起着重要作用,因它不会破坏数据的结构,如在一端将图片转成二进制数据传输到另一端时,还能将它些数据还原成图片。
下面查看它的公有函数:
QDataStream()
QDataStream(QIODevice * d)//对文件等IO设备操作
QDataStream(QByteArray * a, QIODevice::OpenMode mode)//能方操作QByteArray(字节数组类),与类的实际用途相一致
QDataStream(const QByteArray & a)//
~QDataStream()
void setDevice(QIODevice * d)
void setByteOrder(ByteOrder bo)//字节序。有QDataStream::BigEndian(默认)和QDataStream::LittleEndian两种枚举类型,它们的区别,见http://blog.csdn.net/sunshine1314/article/details/2309655
void setFloatingPointPrecision(FloatingPointPrecision precision)//浮点数精度,有QDataStream::SinglePrecision单精度和QDataStream::DoublePrecision双精度。读取和写入时,精度必须一致
void setStatus(Status status)//设置状态,似乎状态的返回值更有用
void setVersion(int v)//由于这个类取决于操作系统的CPU或默认的字符序,在使用不用的Qt版本写的软件读写同一文 件时,可能会有些不同,故最好指定版本,如Qt 5.2的int v为15,Qt 5.1为14,依些递增或递减
int skipRawData(int len)//跳过一定长度的字符,返回实际跳过人数量
void resetStatus()//重置状态,状态的返回值应更有用,具体状态返回值见枚举值
QDataStream & writeBytes(const char * s, uint len)
int writeRawData(const char * s, int len)
bool atEnd() const
ByteOrder byteOrder() const
QIODevice * device() const
FloatingPointPrecision floatingPointPrecision() const
QDataStream & readBytes(char *& s, uint & l)
int readRawData(char * s, int len)
Status status() const
int version() const
QDataStream & operator<<(qint8 i)
QDataStream & operator<<(bool i)
QDataStream & operator<<(quint8 i)
QDataStream & operator<<(quint16 i)
QDataStream & operator<<(qint16 i)
QDataStream & operator<<(qint32 i)
QDataStream & operator<<(quint64 i)
QDataStream & operator<<(qint64 i)
QDataStream & operator<<(quint32 i)
QDataStream & operator<<(float f)
QDataStream & operator<<(double f)
QDataStream & operator<<(const char * s)
QDataStream & operator>>(qint8 & i)
QDataStream & operator>>(bool & i)
QDataStream & operator>>(quint8 & i)
QDataStream & operator>>(quint16 & i)
QDataStream & operator>>(qint16 & i)
QDataStream & operator>>(quint32 & i)
QDataStream & operator>>(qint32 & i)
QDataStream & operator>>(quint64 & i)
QDataStream & operator>>(qint64 & i)
QDataStream & operator>>(float & f)
QDataStream & operator>>(double & f)
QDataStream & operator>>(char *& s)
1、enum QDataStream::Status
Constant | Value | Description |
---|---|---|
QDataStream::Ok | 0 | 流状态正常 |
QDataStream::ReadPastEnd | 1 | 数据流读取已超出结尾 |
QDataStream::ReadCorruptData | 2 | 读取到损坏的数据 |
QDataStream::WriteFailed | 3 | 无法在文件中写入 |
所有函数都是很简单的。下面观察它的典型用法(引自官网)
一对输出与读取同一文件的例子:
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file); //
out << QString("the answer is"); //将一个字符串序列化,并输出到文件
out << (qint32)42; // 输出整数
QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QString str;
qint32 a;
in >> str >> a; // extract "the answer is" and 42
看到这里,你是否发现了它与众不同的地方?没错,在读取时,它仍能分清写入时的两个数据,丝毫不差地还原它们。
QDataStream在写入数据时,保存原有的数据大小等信息。到这里,你应该了解一下文件头部的“魔术数字“:
表示不同文件类型的魔术数字,指定是文件的最开头的几个用于唯一区别其它文件类型的字节,有了这些魔术数字,我们就可以很方便的区别不同的文件,这也使得编程变得更加容易,因为我减少了我们用于区别一个文件的文件类型所要花费的时间。比如,一个JPEG文件,它开头的一些字节可能是类似这样的”ffd8 ffe0 0010 4a46 4946 0001 0101 0047 ……JFIF…..G“,这里”ffd8“就表示了这个文件是一个JPEG类型的文件,”ffe0“表示这是JFIF类型结构。
与此相似,在我们使用QDataStream写入数据时,它不仅写入了实际内容,可同时写入了其它如大小等信息。