QT的文件读写

来源:互联网 发布:工艺仿真及优化概论 编辑:程序博客网 时间:2024/06/03 16:53

一.

QT通过QIODevice为输入输出提供支持。QIODevice是一个封装能够读写字节块”设备“的强有力提取器。

QT包括如下的QIODevice类:

QFile    在本地文件系统和嵌入式资源中存取文件。

QTemporaryFile   在本地文件系统中创建并存取临时文件

QBuffer  从QByteArray中读取或写入数据

QProcess  运行外部程序并处理进程间通信

QTcpSocket  利用TCP在网络上传输数据

QUdpSocket  在网络上发送或接受UDP数据报

QSslSocket  利用SSL/TLS在网络上传输加密数据流


二.

文件读写包括二进制文件读写和文本文件读写

我们先来看看二进制文件读写:

QT中读写二进制文件最简单的方法是通过实例化一个QFile打开文件,然后通过QDataStream对象存取它。QDataStream支持QList<T> QMap<K,T>等容器类以及整形,双精度等基本的C++类,和其它的QT基本类型:QByteArray,QFont,QImage,QPixmap,QString,QVaruiant等等。

例子:

上半部分写文件,下面半部分读文件,这个例子是C++ GUI Qt4编程这本书上的。

#include <QtCore/QtCore>
#include <QApplication>
#include <QImage>
#include <QColor>
#include <QLabel>
int main(int argc,char *argv[])
{
    QApplication app(argc,argv);
  /*  QImage image(":/image/copy.png");//创建一个图片变量
    QMap<QString,QColor> map;//映射表
    map.insert("red",Qt::red);
    map.insert("green",Qt::green);
    map.insert("blue",Qt::blue);
    QFile file("hello.dat");
    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug()<<"failed!";
        return -1;
    }
    QDataStream out(&file);
    out.setVersion(QDataStream::Qt_4_3);
    out<<quint32(0x12345678)<<image<<map;
    qDebug()<<"success!";
    file.close();*/ //必须要close,要不然写不进去
    quint32 n;//读取时的类型一定要和写入时一样
    QImage image;
    QMap<QString,QColor> map;
    QFile file("hello.dat");
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug()<<"failed!";
        return 1;
    }
    QDataStream in(&file);
    in.setVersion(QDataStream::Qt_4_3);
    in>>n>>image>>map;
    qDebug()<<QString::number(n);
    QLabel *label=new QLabel;
    label->setPixmap(QPixmap::fromImage(image));
    label->show();
    qDebug()<<"success";
    QMap<QString,QColor>::const_iterator i;
    for(i=map.constBegin();i!=map.constEnd();++i)
        qDebug()<<i.key()<<":"<<i.value();
    file.close();
    return app.exec();
}

然后来看一下文本文件的读写

虽然二进制文件格式比通常基于文本的格式更加紧凑,但是无法阅读和编辑。QT提供了QTextStream类读写纯文本文件以及如HTML,XML和源代码等其它文本格式的文件。

写文本文件很容易:

int main(int argc,char *argv[])
{
    QApplication app(argc,argv);
    QFile file("hello.txt");
    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug()<<"failed";
        return 1;
    }
    QTextStream out(&file);
    out<<"hello world"<<123<<endl;
    file.close();
    return app.exec();
}
但是读文本比较麻烦,因为文本数据从根本上来说是不确定的。

out<<"hello"<<"world";

读取时如果用in>>str1>>str2,那么str1会是”helloworld“,而str2是空,因为它不知道字符串的长度。

解析器通常通过在QChar上使用>>来一个字符一个字符的读取,或者用QTextStream::readline来一行一行读取,或者QTextStream::readAll()来一次性全部读取。

一行读取

QTextStream in(&file);
    while(!in.atEnd())
    {
        QString line=in.readLine();
    }
也可以用分割器来分割一行从而获取各个部分的值。

QTextStream in(&file);
    while(!in.atEnd())
    {
        QString line=in.readLine();
        QStringList fields=line.split();
        QString line1=fields.takeFirst();   //takefirst()会返回列表中的第一项然后删除它
        QString line2=fields.takeFirst();
        QString line3=fields.takeFirst();
    }
我觉得写文件的时候最好是定义一个格式,读的时候会方便很多。
字符读取

const int TabSize = 8;
    int endlCount = 0;
    int spaceCount = 0;
    int column = 0;
    QChar ch;
    while (!in.atEnd()) {
        in >> ch;
        if (ch == '\n') {
            ++endlCount;
            spaceCount = 0;
            column = 0;
        } else if (ch == '\t') {
            int size = TabSize - (column % TabSize);
            spaceCount += size;
            column += size;
        } else if (ch == ' ') {
            ++spaceCount;
            ++column;
        } else {
            while (endlCount > 0) {
                out << endl;
                --endlCount;
                column = 0;
            }
            while (spaceCount > 0) {
                out << ' ';
                --spaceCount;
                ++column;
            }
            out << ch;
            ++column;
        }
    }
    out << endl;

int endlCount = 0;
    int spaceCount = 0;
    int column = 0;
这三个只是计数器,看看有多少行什么的


0 0