Qt 文件操作 & 容器

来源:互联网 发布:淘宝官方app客户端下载 编辑:程序博客网 时间:2024/05/21 11:19

Qt5

  • QIODevice:所有 I/O 设备类的父类,提供了字节块读写的通用操作以及基本接口;
  • QFlie:访问本地文件或者嵌入资源;
  • QTemporaryFile:创建和访问本地文件系统的临时文件;
  • QBuffer:读写 QByteArray;
  • QProcess:运行外部程序,处理进程间通讯;
  • QAbstractSocket:所有套接字类的父类;
  • QTcpSocket:TCP 协议网络数据传输;
  • QUdpSocket:传输 UDP 报文;
  • QSslSocket:使用 SSL/TLS 传输数据;
  • QFileDevice:Qt5 新增加的类,提供了有关文件操作的通用实现。

QProcess、QTcpSocket、QUdpSoctet 和 QSslSocket 是顺序访问设备,只能从头到尾读下去不能回头。
QFile、QTemporaryFile 和 QBuffer 是随机访问设备,可以访问任意位置任意次数,还可以使用 QIODevice::seek() 函数来重新定位文件访问位置指针。

#include <QApplication>#include <QDebug>#include <QFile>#include <QFileInfo>int main(int argc, char *argv[]){    QApplication app(argc, argv);    QFile file("C:/Users/Aaron/Documents/LenovoHdReport.txt");    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {        qDebug() << "Open file failed.";        return -1;    } else {        while (!file.atEnd()) {            qDebug() << file.readLine(); //一次读一行        }    }    QFileInfo info(file);    qDebug() << info.path();  //返回路径    qDebug() << info.isDir(); //是否是路径    qDebug() << info.isExecutable(); //是否可执行    qDebug() << info.baseName(); //Returns the base name of the file without the path.    qDebug() << info.completeBaseName();//Returns the complete base name of the file without the path.    qDebug() << info.suffix(); //Returns the suffix of the file.    qDebug() << info.completeSuffix();//Returns the complete suffix of the file.    return app.exec();}

complateSuffix , suffix 区别可以直接看文档的例子。


QDataStream 二进制流

QDataStream 提供了基于 QIODevice 的二进制数据的序列化。
数据流是一种二进制流,完全不依赖于底层操作系统、CPU 或者字节顺序(大端或小端)。例如,在安装了 Windows 平台的 PC 上面写入的一个数据流,可以不经过任何处理,直接拿到运行了 Solaris 的 SPARC 机器上读取。由于数据流就是二进制流,因此我们也可以直接读写没有编码的二进制数据,例如图像、视频、音频等。

QDataStream 既能够存取 C++ 基本类型,如 int、char、short 等,也可以存取复杂的数据类型,例如自定义的类。实际上,QDataStream 对于类的存储,是将复杂的类分割为很多基本单元实现的。

    QFile file("file.dat");    if(file.open(QIODevice::WriteOnly|QIODevice::ReadOnly)){        QDataStream out(&file);  //写入        out << QString("the answer is");        out << (qint32)42;        file.close();    }else{        return -1;    }    if(file.open(QIODevice::ReadOnly)){        QDataStream in(&file);  //读取        QString str;        qint32 a = 3;        in>>str>>a;        qDebug()<<str<<a;        file.close();    }

二进制流在写入的时候会在没个数据前面加上这个数据的长度。
注意:读取顺序必须和写入顺序一致。毕竟是二进制数据流,错一位就改不回来了。
而且可以看到先把文件关闭了又打开才读取的数据,因为流数据在写入的时候游标是跟着向后移动的,游标在文件末尾,如果直接读取显然是拿不到数据的。当然也可以用方法:out.device()->seek(0) 将游标重新移动到开头位置。

由于二进制流是纯粹的字节数据,带来的问题是,如果程序不同版本之间按照不同的方式读取(前面说过,Qt 保证读写内容的一致,但是并不能保证不同 Qt 版本之间的一致),数据就会出现错误。因此,我们必须提供一种机制来确保不同版本之间的一致性。

QFile file("file.dat");file.open(QIODevice::WriteOnly);QDataStream out(&file);// 写入魔术数字和版本out << (quint32)0xA0B0C0D0;out << (qint32)123;out.setVersion(QDataStream::Qt_4_0);// 写入数据out << lots_of_interesting_data;

这样一来,在读取文件的时候,先判断魔术数字以及版本的一致性,即可保证。


QTextStream 文本流

QTextStream 的写入和QDataStream并无二致。但读取则不样。因为存取的是文本数据,并不像二进制流一样会存上每个数据的长度。
将上面的例子改成文本流,就会发现 输出时 str == the answer is 42.
而 a 并没有重新赋值。
文本流 可以设置编码格式 stream.setCodec("UTF-8");
另外:另外,为方便起见,QTextStream 同 std::cout 一样提供了很多描述符,被称为 stream manipulators。因为文本文件是供人去读的,自然需要良好的格式(相比而言,二进制文件就没有这些问题,只要数据准确就可以了)。这些描述符是一些函数的简写,我们可以从文档中找到:


Qt 容器

  • QList:这是至今为止提供的最通用的容器类。它将给定的类型 T 的对象以列表的形式进行存储,与一个整型的索引关联。QList 在内部使用数组实现,同时提供基于索引的快速访问。我们可以使用 QList::append() 和 QList::prepend() 在列表尾部或头部添加元素,也可以使用 QList::insert() 在中间插入。相比其它容器类,QList 专门为这种修改操作作了优化。QStringList 继承自 QList。

  • QLinkedList:类似于 QList,除了它是使用遍历器进行遍历,而不是基于整数索引的随机访问。对于在中部插入大量数据,它的性能要优于 QList。同时具有更好的遍历器语义(只要数据元素存在,QLinkedList 的遍历器就会指向一个合法元素,相比而言,当插入或删除数据时,QList 的遍历器就会指向一个非法值)。

  • QVector< T>:用于在内存的连续区存储一系列给定类型的值。在头部或中间插入数据可能会非常慢,因为这会引起大量数据在内存中的移动。

  • QStack< T>:这是 QVector 的子类,提供了后进先出(LIFO)语义。相比 QVector,它提供了额外的函数:push(),pop() 和 top()。

  • QQueue< T>:这是 QList 的子类,提供了先进先出(FIFO)语义。相比 QList,它提供了额外的函数:enqueue(),dequeue() 和 head()。

  • QSet< T>:提供单值的数学上面的集合,具有快速的查找性能。

  • QMap< Key, T>:提供了字典数据结构(关联数组),将类型 T 的值同类型 Key 的键关联起来。通常,每个键与一个值关联。QMap 以键的顺序存储数据;如果顺序无关,QHash 提供了更好的性能。

  • QMultiMap< Key, T>:这是 QMap 的子类,提供了多值映射:一个键可以与多个值关联。

  • QHash< Key, T>:该类同 QMap 的接口几乎相同,但是提供了更快的查找。QHash 以字母顺序存储数据。

  • QMultiHash< Key, T>:这是 QHash 的子类,提供了多值散列。

    遍历器:
    QListIterator< T> 只读遍历器; QMutableListIterator< T> 读写遍历器。其他的容器都一样。

两种容器的遍历方式

QMutableListIterator<int> i(list);while (i.hasNext()) {    if (i.next() > 128) {        i.setValue(128); //也可以直接 i = 128;    }}
QList<QString> list;list << "A" << "B" << "C" << "D";QList<QString>::iterator i;for (i = list.begin(); i != list.end(); ++i) {    *i = (*i).toLower();}

另外 foreach() 也是可以的。

0 0