使用QFile进行文件操作(QFile可以使用FILE *指针,还必须指定AutoCloseHandle)

2023-11-19

QFile类我我们提供了操作文件的常用功能。它是一种io设备,可以用来读写文本文件和二进制文件,也可以用来读写Qt的资源文件。QFile类可以单独使用,该类本身提供了read/write函数,但更方便的方式是,将QFile和QTextStream或QDataStream一起使用。

一般情况下,使用QFile创建对象时,就会把要操作的文件名传递给它。但该类也提供了一个setFileName() 方法,允许我们在任何时候为QFile对象设置要操作的文件名。但是,QFile 只支持"/",不支持"\"。

在构造QFile的对象后,我们可以使用exists() 判断文件是否存在,使用remove() 删除一个文件。在进行实际的内容读写前,需调用open()打开文件,读写结束后,要调用close()关闭文件,也可以写调用一下flush(),冲刷缓冲区。就向我们刚才说的,我们一般使用QDataStream或QTextStream 读写文件,但我们也可以使用QFile继承自QIODevice的函数,如read()、readLine()、readAll()、write()等。除了读写函数外,我们还能使用size() 函数获得文件的大小;使用pos() 或 seek() 函数获取及设置文件读写的位置;使用atEnd() 函数判断是否到达了文件结尾。

直接使用QFile读写文件

          QFile file("in.txt");
          if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
              return;
     
          while (!file.atEnd()) {
              QByteArray line = file.readLine();
              process_line(line);
          }

在此,我们将QIODevice::Text传给了open()函数,该标志是用来告诉Qt将文件中的换行符由"\r\n",转换成"\n"。因为,默认情况下,QFile把文件当做二进制进行读写,不会进行任何的字节转换。

使用流读取文件:

          QFile file("in.txt");
          if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
              return;
     
          QTextStream in(&file);
          while (!in.atEnd()) {
              QString line = in.readLine();
              process_line(line);
          }

QTextStream会把存储在磁盘上的8bit数据转换为16bit的Unicode 字符串QString。默认情况下,QTextStream假定文件使用的是用户系统的本地8bit编码。我们也可以使用QTextStream::setCodec() 函数还改变这种行为。

当使用QFile,QFileInfo和QDir类去操作文件系统时,你可以使用Unicode编码的文件名。在Unix平台上,这些文件名会被转换成8-bit编码。但如果你想使用标准c++ API或者平台特定的API去访问文件,那么你可以使用encodeName() 和 decodeName() 函数在Unicode文件名和8-bit文件名之间进行转换。

在Unix平台下,存在一些特殊的系统文件,例如/proc目录下,对这个文件调用size() 总是返回0,然而,你还是能够从此类文件中读取到数据;这些数据是为了相应你的read() 函数而间接产生出来的。但是,在这种情况下,你不能使用atEnd() 来判断是否还有数据可读(因为atEnd() 对于大小为0的文件返回true)。相反,你应该调用readAll(),或 反复调用read()、readLine()知道没有数据可读为止。如下代码所示,我们使用QTextStream一行一行的读取/proc/modules文件:

          QFile file("/proc/modules");
          if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
              return;
     
          QTextStream in(&file);
          QString line = in.readLine();
          while (!line.isNull()) {
              process_line(line);
              line = in.readLine();
          }


其实,除了上面使用的QFile从QIODevice继承的open() 函数外,QFile本身也为我们提供了两个open() 函数:

    bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags = DontCloseHandle)
    bool open(int fd, OpenMode mode, FileHandleFlags handleFlags = DontCloseHandle)


第一个open() 会按一定的模式打开一个现存的文件指针。同时,可以再指定额外的标志。如下代码所示:

      #include <stdio.h>
     
      void printError(const char* msg)
      {
          QFile file;
          file.open(stderr, QIODevice::WriteOnly);
          file.write(msg, qstrlen(msg));        // write to stderr
          file.close();
      }

当一个QFile已这种方式打开时,那么后续的close() 函数的作用会受到AutoCloseHandle标志的影响。如果指定了该标志,并且这个open() 函数调用成功了,那么后续再QFile对象上调用close() 会关闭底层文件句柄。否则,若没指定这个标志,close()函数不会真正的关闭底层文件句柄,而只是冲刷 了一下缓冲区。如下测试代码所示:

    #include <QCoreApplication>
    #include <QFile>
    #include <cstdio>
     
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
     
        FILE *pf = fopen("test.txt", "wb");
        if(pf == nullptr)
            return 0;

   

// bool QFile::open(FILE *fh, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)

      
        QFile file;
        file.open(pf, QIODevice::WriteOnly); //1
        //file.open(pf, QIODevice::WriteOnly, QFileDevice::AutoCloseHandle); //2
        file.write("hello");
        file.close();
        fwrite("world", strlen("world"), 1, pf);
     
        return a.exec();
    }

当我们使用 1处的方式打开文件指针,即不指定AutoCloseHandle标志,则close() 函数后的“world”是可以继续被写入文件的

使用2处的方式打开文件指针,则“world”并不会再被写入文件,因为底层文件已关闭。

第二个open() 函数与此类似,只不过其是按一定模式打开一个现存的文件描述符。AutoCloseHandle标志也会影响后续的close()函数。同时,如果QFile已这种方式打开,那么它会被自动地设置为raw mode,这意味着文件的输入、输出函数的执行会变慢。如果你遇到了性能问题,你应该尝试使用其他的打开函数。

至于其他的成员函数,比如文件的删除、重命名,文件访问权限的设置,Qt的帮助文档已讲的很清除,大家可以在使用时随时查看即可。

Qt 官方手册:

bool QFile::open(FILE *fh, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)

This is an overloaded function.
Opens the existing file handle fh in the given mode. handleFlags may be used to specify additional options. Returns true if successful; otherwise returns false.
Example:

  #include <stdio.h>

  void printError(const char* msg)
  {
      QFile file;
      file.open(stderr, QIODevice::WriteOnly);
      file.write(msg, qstrlen(msg));        // write to stderr
      file.close();
  }

When a QFile is opened using this function, behaviour of close() is controlled by the AutoCloseHandle flag. If AutoCloseHandle is specified, and this function succeeds, then calling close() closes the adopted handle. Otherwise, close() does not actually close the file, but only flushes it.

Warning:
If fh does not refer to a regular file, e.g., it is stdin, stdout, or stderr, you may not be able to seek(). size() returns 0 in those cases. See QIODevice::isSequential() for more information.
Since this function opens the file without specifying the file name, you cannot use this QFile with a QFileInfo.

Note for the Windows Platform
fh must be opened in binary mode (i.e., the mode string must contain 'b', as in "rb" or "wb") when accessing files and other random-access devices. Qt will translate the end-of-line characters if you pass QIODevice::Text to mode. Sequential devices, such as stdin and stdout, are unaffected by this limitation.
You need to enable support for console applications in order to use the stdin, stdout and stderr streams at the console. To do this, add the following declaration to your application's project file:

  CONFIG += console

See also close().

bool QFile::open(FILE *fh, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)

QIODevice::OpenMode

enum QIODevice::OpenModeFlag
flags QIODevice::OpenMode
This enum is used with open() to describe the mode in which a device is opened. It is also returned by openMode().
Constant Value Description
QIODevice::NotOpen 0x0000 The device is not open.
QIODevice::ReadOnly 0x0001 The device is open for reading.
QIODevice::WriteOnly 0x0002 The device is open for writing. Note that, for file-system subclasses (e.g. QFile), this mode implies Truncate unless combined with ReadOnly, Append or NewOnly.
QIODevice::ReadWrite ReadOnly | WriteOnly The device is open for reading and writing.
QIODevice::Append 0x0004 The device is opened in append mode so that all data is written to the end of the file.
QIODevice::Truncate 0x0008 If possible, the device is truncated before it is opened. All earlier contents of the device are lost.
QIODevice::Text 0x0010 When reading, the end-of-line terminators are translated to '\n'. When writing, the end-of-line terminators are translated to the local encoding, for example '\r\n' for Win32.
QIODevice::Unbuffered 0x0020 Any buffer in the device is bypassed.
QIODevice::NewOnly 0x0040 Fail if the file to be opened already exists. Create and open the file only if it does not exist. There is a guarantee from the operating system that you are the only one creating and opening the file. Note that this mode implies WriteOnly, and combining it with ReadWrite is allowed. This flag currently only affects QFile. Other classes might use this flag in the future, but until then using this flag with any classes other than QFile may result in undefined behavior. (since Qt 5.11)
QIODevice::ExistingOnly 0x0080 Fail if the file to be opened does not exist. This flag must be specified alongside ReadOnly, WriteOnly, or ReadWrite. Note that using this flag with ReadOnly alone is redundant, as ReadOnly already fails when the file does not exist. This flag currently only affects QFile. Other classes might use this flag in the future, but until then using this flag with any classes other than QFile may result in undefined behavior. (since Qt 5.11)

 QFileDevice::FileHandleFlags

enum QFileDevice::FileHandleFlag
flags QFileDevice::FileHandleFlags
This enum is used when opening a file to specify additional options which only apply to files and not to a generic QIODevice.
Constant Value Description
QFileDevice::AutoCloseHandle 0x0001 The file handle passed into open() should be closed by close(), the default behavior is that close just flushes the file and the application is responsible for closing the file handle. When opening a file by name, this flag is ignored as Qt always owns the file handle and must close it.
QFileDevice::DontCloseHandle 0

If not explicitly closed, the underlying file handle is left open when the QFile object is destroyed.

 

 

————————————————
版权声明:本文为CSDN博主「求道玉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Amnes1a/article/details/65434670

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用QFile进行文件操作(QFile可以使用FILE *指针,还必须指定AutoCloseHandle) 的相关文章

随机推荐

  • pc连接用access,交换机互联用trunk

    实验目的 同一个里vlan下面的所有主机可以相连 vlan10和vlan100可以相通 实验前提 把pc的基本配置做完 让他们在一个网段里 给pc1和pc3按照要求用vlan10 pc2用vlan100 交换机1 首先让交换机创建10 10
  • html中使用js实现体彩11选5随机选号

    体彩11选5随机选号 页面预览 代码实现
  • OpenCV简单应用(一、摄像头拍照)

    1 首先安装OpenCV 当然所用电脑要有摄像头 且接入网络 比较简单粗暴的做法是到Python所在的目录下 Scripts下运行 pip install opencv python 2 以下代码是开启摄像头 按任意键退出 import c
  • QT2023新版安装教程

    目录 前言 一 QT在线安装包下载 1 官方网站 2 镜像 清华大学 二 QT安装 1 更换安装源 2 安装界面 3 组件选择 重点 参考 Qt2023新版保姆级 安装教程 前言 本文主要介绍2023新版QT安装过程 希望能帮到大家 一 Q
  • mybatisplus是什么?

    Mybatis Plus 简称为Mybatis 或MP 是一个开源的Mybatis增强框架 它是在Mybatis基础上进行了扩展和增强 Mybatis Plus旨在简化开发过程 提高代码的开发效率 并提供更多的便捷功能 Mybatis Pl
  • 仿网易云音乐小程序

    一 程序描述 仿网易云音乐小程序 调用网易云API真实接口 实现了音乐播放 音乐切换 歌词显示 搜索音乐 视频播放 用户登录退出等功能 以下是效果展示 仿网易云小程序 二 代码介绍 1 目录介绍 2 搜索 代码讲解 实现思路 先把搜索的静态
  • 台式电脑切换集成显卡和独立显卡

    台式电脑切换集成显卡和独立显卡 1 背景 2 认识 3 步骤 3 1 确认是否有两个显卡以及当前显示器连接显卡 3 2 更新驱动 3 3 确认显示器连接接口 3 4 显卡设置 4 总结 1 背景 发现电脑在处理画面时有非常卡顿 想着电脑装的
  • html中图片热区链接怎么设置,html图像热区链接做好之后怎么上传到网页上让别人打开?...

    html图像热区链接做好之后怎么上传到网页上让别人打开 以下文字资料是由 历史新知网www lishixinzhi com 小编为大家搜集整理后发布的内容 让我们赶快一起来看一下吧 图像热区链接做好之后怎么上传到网页上让别人打开 做的是静态
  • 使用session实现同一账号只能同时一个人使用

    使用session实现同一账号只能同时一个人使用 今天我们要讲的就是 实现同一个账号只能同一时间让一个人使用 实现起来也是非常的简单 其实我这里讲到的是我前几天做出来的一个大概核心代码和核心思路 我也是查遍了很多网站 看了很多人的源码然后都
  • QT绘图之自动缩放画线和点

    需求 用 作为画板 把纸条缩放到 上 纸条长度不定 宽度固定 纸条上任意位置画点或者线 点距或者线距不固定 点数和线数也不固定 要成比例映射到 上直观显示 话不多说 上代码 ool sprayer Widget eventFilter QO
  • 导入Unity 2D Animation插件没有生效

    导入Unity 2D Animation后 打开Sprite Editor发现没有Skinning Editor选项 这可能是因为导入插件后与项目原有的Plugin下的库产生冲突导致的 这时候点击Packages Editor Unity
  • 线程和线程池

    线程和线程池 并发和并行 并发是指在单个CPU核心上 多个线程占用不同的CPU时间片 但由于每个线程占用的CPU时间片非常短 比如10ms 看起来就像是多个线程在共同执行一样 但在微观物理上看其实还是串行执行的 这样的场景称作并发 并行是指
  • QQ小程序服务器内部错误,网络

    网络 使用说明 在小程序 小游戏中使用网络相关的 API 时 需要注意下列问题 请开发者提前了解 1 服务器域名配置 每个QQ小程序需要事先设置一个通讯域名 小程序只可以跟指定的域名与进行网络通信 包括普通 HTTPS 请求 qq requ
  • 工作队列(workqueue)

    转载于 http blog csdn net angle birds article details 8448070 项目需要 在驱动模块里用内核计时器timer list实现了一个状态机 郁闷的是 运行时总报错 Scheduling wh
  • 仿鸟云IDC模板 最新修复创梦虚拟主机管理系统+主控模板+鸟云模板源码

    介绍 最近仿鸟云的 IDC 模板 好像很火 很早以前做了一个和鸟云早期的模板 但后来服务器没备份 数据丢失了 此为近期找到的一份新的鸟云源码 如果大家有需求 可以进行长期更新维护此套模板 做到更精 在 Global asa 文件的最后一行之
  • SpringBoot配置多个Redis数据源

    一 添加依赖
  • type traits浅析

    1 G2 9的type trait G2 9的type trait用一个泛化类模板来定义各种类型的属性 默认都是假的 然后给每一种类型都添加了偏特化版本 这样的缺点是每写一个类 都要添加一个偏特化的模板类 十分麻烦 2 C 改进的type
  • 渗透:vulnhub DC系列之DC1

    DC系列之DC1 一 靶机配置及说明 下载地址 https www vulnhub com entry dc 1 292 靶机 DC1 VMware IP 192 168 49 152 攻击机 kali2018 IP 192 168 49
  • 姿态估计与人体动作识别的多任务深度学习模型

    最近在做一个人体康复训练的项目 一开始考虑到人体康复训练需要肢体的细微动作 所以先使用人体姿态估计识算法提取骨骼点 再根据人体骨骼点来识别动作 后来发现也不一定这样 并组合成一个端对端的模型 正好找到了最近的一篇论文 2D 3D Pose
  • 使用QFile进行文件操作(QFile可以使用FILE *指针,还必须指定AutoCloseHandle)

    QFile类我我们提供了操作文件的常用功能 它是一种io设备 可以用来读写文本文件和二进制文件 也可以用来读写Qt的资源文件 QFile类可以单独使用 该类本身提供了read write函数 但更方便的方式是 将QFile和QTextStr