Qt之Qfile读取文件操作

文件系统:
  文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。Qt 通过QIODevice提供了对 I/O 设备的抽象,这些设备具有读写字节块的能力。下面是 I/O 设备的类图(Qt5):
在这里插入图片描述
   QIODevice:所有 I/O 设备类的父类,提供了字节块读写的通用操作以及基本接口;
   QFileDevice:Qt5新增加的类,提供了有关文件操作的通用实现。
   QFlie:访问本地文件或者嵌入资源;
   QTemporaryFile:创建和访问本地文件系统的临时文件;
   QBuffer:读写QbyteArray, 内存文件;
   QProcess:运行外部程序,处理进程间通讯;
   QAbstractSocket:所有套接字类的父类;
   QTcpSocket:TCP协议网络数据传输;
   QUdpSocket:传输 UDP 报文;
   QSslSocket:使用 SSL/TLS 传输数据;

文件系统分类:
   顺序访问设备:
是指它们的数据只能访问一遍:从头走到尾,从第一个字节开始访问,直到最后一个字节,中途不能返回去读取上一个字节,这其中,QProcess、QTcpSocket、QUdpSoctet和QSslSocket是顺序访问设备。
   随机访问设备:
可以访问任意位置任意次数,还可以使用QIODevice::seek()函数来重新定位文件访问位置指针,QFile、QTemporaryFile和QBuffer是随机访问设备,

基本文件操作:
  文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。在所有的 I/O 设备中,文件 I/O 是最重要的部分之一。因为我们大多数的程序依旧需要首先访问本地文件(当然,在云计算大行其道的将来,这一观点可能改变)。QFile提供了从文件中读取和写入数据的能力。
我们通常会将文件路径作为参数传给QFile的构造函数。不过也可以在创建好对象最后,使用setFileName()来修改
  QFile主要提供了有关文件的各种操作,比如打开文件、关闭文件、刷新文件等。我们可以使用QDataStreamQTextStream类来读写文件,也可以使用QIODevice类提供的read()、readLine()、readAll()以及write()这样的函数。值得注意的是,有关文件本身的信息,比如文件名、文件所在目录的名字等,则是通过QFileInfo获取,而不是自己分析文件路径字符串。
**举个例子:**设计一个文本框,读写数据,保存在本地文件下
在这里插入图片描述
写文件:

void Widget::on_btn_write_clicked()
{
    QString path = QFileDialog::getSaveFileName(this,"write","../");
    if(path.isEmpty() == false)
    {
       QFile file;            //创建对象
       file.setFileName(path);
       //打开文件,只写
       bool isok = file.open(QIODevice::WriteOnly);
       if(isok == true)
       {
           //获取编辑区的内容
           QString str = ui->textEdit->toPlainText();
           //把读取到的文本写进文件file对象中
           //由于文件写函数是qbytearray类型的数据,所以需要在写之前将str转换成bytearray类型
           //在qt中有直接转换的函数,toutf8();
            file.write(str.toUtf8());
       }
    file.close();
    }
}

1:第一步是设置文件路径QFileDialog提供了一个对话框,允许用户选择文件或者目录,也允许用户遍历文件系统,用以选择一个或多个文件或者目录。
2:设置文本的名字或者路径
3:打开文本 ,file.open()和file.close()一起用。实际上qt中 文本在关闭时数据才会真正写如进去。你可以不写关闭函数 然后看看文件是否写进去的数据。我们在打开文本的时候,是可以选择打开的格式的,
在这里插入图片描述
枚举值 描述
QIODevice::NotOpen    未打开
QIODevice::ReadOnly    以只读方式打开
QIODevice::WriteOnly    以只写方式打开
QIODevice::ReadWrite    以读写方式打开
QIODevice::Append    以追加的方式打开,新增加的内容将被追加到文件末尾
QIODevice::Truncate    以重写的方式打开,在写入新的数据时会将原有 数据全部清除,                   游标设置在文件开头。
QIODevice::Text    在读取时,将行结束符转换成 \n;在写入时,将行结束符转换成本地格                   式,例如 Win32 平台上是 \r\n
QIODevice::Unbuffered    忽略缓存

读文件:

void Widget::on_btn_read_clicked()
{
    QString path = QFileDialog::getOpenFileName(this,"打开","../");
    if(path.isEmpty() == false)
    {
        //创建文件对象
        QFile file(path);

        bool isok = file.open(QIODevice::ReadOnly); //只读模式打开
        if(isok == true)
         {
#if 1
             //读文件
            QByteArray array =  file.readAll();

            //将数据写进文本框中
            ui->textEdit->setText(QString(array));
#else
          //一行一行的读
            QByteArray array;
            while(file.atEnd() == false)
            {
                array += file.readLine();
            }
             ui->textEdit->setText(QString(array).toUtf8().data());

#endif
}
        file.close();
        //获取文件信息
        QFileInfo info(path);
        qDebug()<<"文件名字:"<< info.fileName();
        qDebug()<<"文件后缀:"<< info.suffix();
        qDebug()<<"文件大小:"<< info.size();
        qDebug()<<"文件创建时间:"<< info.created().toString("yyyy-MM-dd hh:mm:ss"); //yyyy代表年 MMd

    }
}

读文件跟写文件差不多,这里我们主要说一下,如果我们需要文件的相关信息,比如路径,大小,格式等。并不是去索引这个文件路径然后获取相关信息。在qt中有一个QFileInfo的类,他有很多的函数 是用来获取文本信息的。例如:
 isDir()检查该文件是否是目录;
 isExecutable() 检查该文件是否是可执行文件等。
 baseName() 可以直接获得文件名;
 completeBaseName() 获取完整的文件名
 suffix() 则直接获取文件后缀名。
 completeSuffix() 获取完整的文件后缀

        //获取文件信息
        QFileInfo info(path);
        qDebug()<<"文件名字:"<< info.fileName();
        qDebug()<<"文件后缀:"<< info.suffix();
        qDebug()<<"文件大小:"<< info.size();
        qDebug()<<"文件创建时间:"<< info.created().toString("yyyy-MM-dd hh:mm:ss"); 

以上我们读写文件方式都是使用的QIODevice提供的函数,接下来我们看看怎么使用QDataStream二进制读写文件。
  QDataStream提供了基于QIODevice的二进制数据的序列化。数据流是一种二进制流,这种流完全不依赖于底层操作系统、CPU 或者字节顺序(大端或小端)。例如,在安装了 Windows 平台的 PC 上面写入的一个数据流,可以不经过任何处理,直接拿到运行了 Solaris 的 SPARC 机器上读取。由于数据流就是二进制流,因此我们也可以直接读写没有编码的二进制数据,例如图像、视频、音频等。
  QDataStream既能够存取 C++ 基本类型,如 int、char、short 等,也可以存取复杂的数据类型,例如自定义的类。实际上,QDataStream对于类的存储,是将复杂的类分割为很多基本单元实现的。
二进制文件写操作:

    //创建文件 对象
    QFile file("../test.txt");
    bool isok = file.open(QIODevice::WriteOnly);
    if(isok == true)
    {
        //创建数据流,和file文件关联起来,向数据流里面输入数据时,就是往文件里面写数据
        QDataStream stream(&file);   //stream 是二进制的数据,在文本显示为乱码

     stream << QString("主要看气质") << 250;
     file.close();
    }

二进制文件读操作:把写进去的数据读出来

    //创建文件 对象
    QFile file("../test.txt");
    bool isok = file.open(QIODevice::ReadOnly);
    if(isok == true)
    {
        QDataStream stream(&file);
        //读取数据时 按照写入的顺序读取
        QString str;
        int a;
        stream >> str >>a ;
        cout << str.toUtf8().data() << a;
    }

在这里插入图片描述
  唯一需要注意的是,你必须按照写入的顺序,将数据读取出来。顺序颠倒的话,程序行为是不确定的,严重时会直接造成程序崩溃 就是我先写的qstring的值,然后再写的int值。我们在读取的时候也是先取出qstring的值 然后在读取int型的值。循序不能出错

  那么,既然QIODevice提供了read()、readLine()之类的函数,为什么还要有QDataStream呢?QDataStream同QIODevice有什么区别?区别在于,QDataStream提供流的形式,性能上一般比直接调用原始 API 更好一些。

文本文件读写

虽然QTextStream的写入内容与QDataStream一致,区别在于读取时不一致:

QDataStream中读取数据时,stream >> str >>a ; cout << str.toUtf8().data() << a;
QTextStream中读取数据时,stream >>str ; cout << str;
在这里插入图片描述
两者的输出结果都是一样的,可以看出在使用QTextStream的时候,不需要定义一个int的变量a来存储读出的int类型的数据250。这是因为当使用QDataStream写入的时候,实际上会在要写入的内容前面,额外添加一个这段内容的长度值。而以文本形式写入数据,是没有数据之间的分隔的。

  • 23
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值