【Qt学习】08:文件读写操作

2023-11-06

文件读写操作


文件操作是应用程序必不可少的部分,Qt 作为一个通用开发库提供了跨平台的文件操作能力。Qt 通过QIODevice提供了对 I/O 设备的抽象,这些设备具有读写字节块的能力,以下是 I/O 设备的类图:

在这里插入图片描述

  1. QIODevice:所有 I/O 设备类的父类,提供了字节块读写的通用操作以及基本接口;
  2. QFileDevice:Qt5新增加的类,提供了有关文件操作的通用实现。
  3. QFlie:访问本地文件或者嵌入资源;
  4. QTemporaryFile:创建和访问本地文件系统的临时文件;
  5. QBuffer:读写QbyteArray, 内存文件;
  6. QProcess:运行外部程序,处理进程间通讯;
  7. QAbstractSocket:所有套接字类的父类;
  8. QTcpSocket:TCP协议网络数据传输;
  9. QUdpSocket:传输 UDP 报文;
  10. QSslSocket:使用 SSL/TLS 传输数据;
  • 顺序访问设备:数据访问从头走到尾,从第一个字节开始访问直到最后一个字节,中途不能返回去读取上一个字节,这其中QProcess、QTcpSocket、QUdpSoctet和QSslSocket是顺序访问设备。

  • 随机访问设备:可以访问任意位置任意次数,还可以使用QIODevice::seek()函数来重新定位文件访问位置指针,QFile、QTemporaryFile和QBuffer是随机访问设备,

一、文件操作

1.QFile

在I/O设备中文件I/O是最重要的部分之一,大多数程序依旧需要首先访问本地文件,QFile提供了从文件中读取和写入数据的能力。

将文件路径作为参数传给QFile的构造函数,使用setFileName()来修改。QFile需要使用/作为文件分隔符,不过它会自动将其转换成操作系统所需要的形式,

QFile的有关操作:

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QString filepath = nullptr;
private:
    Ui::MainWindow *ui;
};

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
    //点击选取文件按钮 弹出文件对话框 读取并显示文件内容
    connect(ui->open, &QPushButton::clicked, this, [=](){
        //1.弹出文件选取对话框 并在文件选择后获取到文件路径
        filepath = QFileDialog::getOpenFileName(this, "select a file", "C:\\Users\\Polaris\\Desktop");
        //2.将文件路径放入到lineEdit组件中
        ui->lineEdit->setText(filepath);
        //3.读取文件中的内容 并将内容放入到textEdit组件中(QFile默认支持utf-8)
        QFile file(filepath);
        //3-1.设置打开方式
        file.open(QIODevice::ReadOnly);
        //3-2.文件读取
        QByteArray array;
        //QByteArray array = file.readAll();
        while (!file.atEnd()) { array += file.readLine(); }
        ui->textEdit->setText(array);//自动进行了类型转换
        //QTextCodec *codec = QTextCodec::codecForName("gbk");//设置支持的编码格式
        //ui->textEdit->setText(codec->toUnicode(array));//将array中的内容都转为gbk格式
        file.close();
    });

    //点击保存文件按钮 将文件修改保存到磁盘中
    connect(ui->save, &QPushButton::clicked, this, [=](){
        if (filepath == nullptr) {
            qDebug() << "please select a file first!~";
            return;
        }
        QString content = ui->textEdit->toPlainText();
        QFile file(filepath);
        file.open(QIODevice::WriteOnly);
        file.write(content.toUtf8().data());
        file.close();
        qDebug() << "write success!~";
    });
}

2.QFileInfo

//点击选取文件按钮 弹出文件对话框 读取并显示文件内容
connect(ui->open, &QPushButton::clicked, this, [=](){
    //1.弹出文件选取对话框 并在文件选择后获取到文件路径
    filepath = QFileDialog::getOpenFileName(this, "select a file", "C:\\Users\\Polaris\\Desktop");
    //2.将文件路径放入到lineEdit组件中
    ui->lineEdit->setText(filepath);
    //3.读取文件中的内容 并将内容放入到textEdit组件中(QFile默认支持utf-8)
    QFile file(filepath);
    //3-1.设置打开方式
    file.open(QIODevice::ReadOnly);
    //3-2.文件读取
    QByteArray array;
    //QByteArray array = file.readAll();
    while (!file.atEnd()) { array += file.readLine(); }
    ui->textEdit->setText(array);//自动进行了类型转换
    //QTextCodec *codec = QTextCodec::codecForName("gbk");//设置支持的编码格式
    //ui->textEdit->setText(codec->toUnicode(array));//将array中的内容都转为gbk格式
    file.close();

    //4.读取文件属性信息
    QFileInfo info(filepath);
    qDebug() << "filename:" << info.fileName();
    qDebug() << "filepath:" << info.filePath();
    qDebug() << "Size:" << info.size();
    qDebug() << "Suffix:" << info.suffix();
    qDebug() << "creatTime:" << info.created().toString("yyyy/MM/dd hh:mm:ss");
    qDebug() << "updateTime:" << info.lastModified().toString("yyyy-MM-dd hh:mm:ss");
});

可以使用QFileInfo获取有关该文件的信息,QFileInfo有很多类型的函数,比如:

  • isDir()检查该文件是否是目录;
  • isExecutable() 检查该文件是否是可执行文件等。
  • baseName() 可以直接获得文件名;
  • completeBaseName() 获取完整的文件名
  • suffix() 则直接获取文件后缀名。
  • completeSuffix() 获取完整的文件后缀

二、二进制文件读写

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

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

结合QIODevice,QDataStream可以很方便地对文件、网络套接字等进行读写操作。

QFile file("C:\\Users\\Polaris\\Desktop\\file.dat");
file.open(QFile::WriteOnly);//设置打开方式
QDataStream out(&file);
out << QString("this is a binary file write & save test.");
out << QString("today is a good day!~");
out << QString("how old are you?");
out << (qint32)23;
file.close();//如果不想关闭文件可以使用file.flush();
  1. 首先选择并打开一个文件,然后将刚刚创建的file对象的指针传递给一个QDataStream实例out,类似于std::cout标准输出流,
  2. QDataStream也重载了输出重定向<<运算符,逐行将QString字符串和数字输出到数据流中,由于out对象建立在file之上因此相当于将问题和答案写入file。
  3. 最好使用 Qt 整型来进行读写,比如程序中的qint32,这保证了在任意平台和任意编译器都能够有相同的行为。

如果省流掉最后一行代码file.close()就会得到一个写入任何数据的空白文件,这是因为file没有正常关闭。为性能起见,数据只有在文件关闭时才会真正写入。因此必须在最后添加一行代码:

接下来将存储到文件中的答案取出来

QFile file("C:\\Users\\Polaris\\Desktop\\file.dat");
file.open(QFile::ReadOnly);//设置打开方式
QDataStream in(&file);
QString str;
qint32 num;
in >> str >> num;
file.close();//如果不想关闭文件可以使用file.flush();

注意:必须按照写入的顺序将数据读取出来,如果顺序颠倒程序行为是不确定的,严重时会直接造成程序崩溃。

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

三、文本文件读写

相较于二进制文件,文本文件是一种人可读的文件。操作这种文件需要使用QTextStream类,QTextStream和QDataStream的使用类似,只不过它是操作纯文本文件的。

QTextStream会自动将 Unicode 编码同操作系统的编码进行转换,该操作对开发人员是透明的。它也会将换行符进行转换,同样不需要自己处理。QTextStream使用 16 位的QChar作为基础的数据存储单位,同样也支持 C++ 标准类型(实际上这是将这种标准类型与字符串进行了相互转换)。

QTextStream同QDataStream的使用基本一致,

QFile file("C:\\Users\\Polaris\\Desktop\\file.dat");
file.open(QFile::ReadOnly | QFile::Truncate);//以只写并且覆盖已有内容的形式操作文件
QTextStream out(&file);
out << QString("this is a binary file write & save test.");
out << QString("today is a good day!~");
out << QString("how old are you?");
out << (qint32)23;
file.close();//如果不想关闭文件可以使用file.flush();

这里open()函数中增加了QIODevice::Truncate打开方式:

枚举值 描述
QIODevice::NotOpen 未打开
QIODevice::ReadOnly 以只读方式打开
QIODevice::WriteOnly 以只写方式打开
QIODevice::ReadWrite 以读写方式打开
QIODevice::Append 以追加的方式打开新增加的内容将被追加到文件末尾
QIODevice::Truncate 以重写的方式打开,在写入新的数据时会将原有数据全部清除,游标设置在文件开头。
QIODevice::Text 在读取时,将行结束符转换成 \n;在写入时,将行结束符转换成本地格式,例如 Win32 平台上是 \r\n
QIODevice::Unbuffered 忽略缓存

虽然QTextStream的写入内容与QDataStream一致,但是读取时却会有些困难:

QFile file("C:\\Users\\Polaris\\Desktop\\file.dat");
file.open(QFile::ReadOnly);//以只写并且覆盖已有内容的形式操作文件
QTextStream in(&file);
QString str;
qint32 num;
in >> str >> num;
file.close();//如果不想关闭文件可以使用file.flush();

在使用QDataStream的时候代码很方便,但使用了QTextStream时却有所不同,使用QDataStream写入的时候,实际上会在要写入的内容前面,额外添加一个这段内容的长度值。

而以文本形式写入数据,是没有数据之间的分隔的。因此使用文本文件时很少会将其分割开来读取,而是使用诸如使用:

  1. QTextStream::readLine() 读取一行
  2. QTextStream::readAll()读取所有文本

默认情况下,QTextStream的编码格式是 Unicode,如果我们需要使用另外的编码,可以使用 stream.setCodec("UTF-8"); 这样的函数进行设置。

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

【Qt学习】08:文件读写操作 的相关文章

随机推荐

  • Flutter 的键值存储数据库

    Flutter 键值存储数据库 键值存储是开发中十分常见的需求 在Flutter开发中 一般使用 shared preferences 插件来实现 shared preferences 本质上就是将键值对保存到一个XML文件中进行持久化 而
  • Spring Boot请求403 Forbidden错误

    欢迎关注笔者的微信公众号 在项目中引入了Spring Security框架做权限控制 但是出于调试的方便 在开始的时候就禁用了Spring Security 计划到项目后期再专门开发 但是 在调试的过程中发现 Postman发出的请求后台无
  • 语音识别芯片LD3320介绍再续

    语音识别芯片LD3320驱动程序 1 芯片复位 复位就是对LD3320芯片的第47腿 RSTB 发送低电平 然后需要对片选CS做一次拉低 拉 高的操作 以激活内部DSP 按照以下顺序 void LD reset RSTB 1 delay 1
  • Python脚本,实现验证码识别

    别验证码是一个很复杂的任务 需要使用计算机视觉和机器学习算法 这里我只能提供一个大致的思路和代码示例 还需要进行相应的调整和补充 import tensorflow as tf from PIL import Image import nu
  • airtest上的滑动操作swipe

    正常来说 方法一的滑动是生效的 但是在页面有蒙层或是其他怪异的情况下 可能就不生效了 再用方法二 方法一 获取设备的高度和宽度 width height device get current resolution 校准滑动的起点和终点 因为
  • 电容滤波笔记

    电容滤波效果 公式 容抗 F 1000Hz 干扰频率 C 1000uF X C 1 2
  • linux 修改jdk版本 /usr/src/jdk-11.0.11/bin/java: 无法执行二进制文件

    下载的jdk版本与linux匹配不正确 更换成上图中就可以了
  • 关于尚硅谷禹神Vue视频四十二级v-cloak,delay_server服务器服务器的替代方案

    关于四十二级v cloak的替代方案 资料没找到那个delay server服务器 手写了一个替代的代码 有的话发我一下谢谢 吃瓜 原视频链接 http 尚硅谷Vue2 0 Vue3 0全套教程丨vuejs从入门到精通 https www
  • flex 间距_聊一聊Flex布局

    Flex布局目前对于前端来说已经是一个非常熟悉且常用的布局方案了 有了它 我们很大程度上就可以避免原来让人头秃的正常流布局带来的很多IFC inline formatting context 问题 随着浏览器的支持性不断增强 基本上我们日常
  • 双系统下怎么卸载linux系统,双系统怎么卸载其中一个操作系统 双系统卸载其中一个操作系统方法...

    一 WIN7 XP 卸载XP 1 登录win7 放入xp光盘 或者用虚拟光驱加载镜像 2 点击 开始 运行 输入 C boot bootsect exe nt52 all force 这里假设C盘为xp安装盘符 回车运行 3 重启电脑 发现
  • 招聘30000名应届生,研发占80%,秋招之光还得是比亚迪!

    金秋9月 一年一度的 秋招 在互联网大厂中如期打响 在过去的一年 互联网圈子经历了几番 动荡 今年 各大公司在人才储备 岗位设置等方面显现出哪些新动向 整个行业的趋势如何 本篇文章我们来一探究竟 01 超3万名应届生入职 比亚迪成为 秋招之
  • bean的生命周期

    六 bean的生命周期 https liayun blog csdn net article details 110670961 Bean 的初始化和销毁 1 Bean注解中使用init method属性和destroy method属性来
  • 【web安全】——文件包含漏洞

    作者名 Demo不是emo 主页面链接 主页传送门 创作初心 一切为了她 座右铭 不要让时代的悲哀成为你的悲哀专研方向 网络安全 数据结构 每日emo 可后来 除了梦以外的地方 我再也没有见过你 目录 一 初识文件包含漏洞 1 简析文件包含
  • Linux系统的镜像文件iso下载地址

    打开如下地址 http archive kernel org centos vault 6 1 isos x86 64 然后选择 CentOS 6 1 x86 64 bin DVD1 iso 即可下载
  • 【华为OD机试真题 python】 字符串比较【2022 Q4

    前言 华为OD笔试真题 python 专栏含华为OD机试真题 华为面试题 牛客网华为专栏真题 如果您正在准备华为的面试 或者华为od的机会 有任何想了解的可以私信我进行交流 我会尽可能的给一些建议 和帮您解答 PS 文中答案仅供参考 不能照
  • Visio图片加全边框

    Visio插入图片 想给每一个图都加边框 一个方法是画矩形框 如果是很多图片的话很麻烦 另一个方法 选中图片 然后选 线条 但是发现只围一半 调整线条宽度 欧了
  • 转:Oracle RAC:生产环境下的搭建过程

    原帖 http tech it168 com a2012 0928 1404 000001404498 shtml Oracle RAC 生产环境下的搭建过程 2012年09月29日00 05 it168网站原创 作者 刘炳林 编辑 王玉圆
  • python语言控制结构是指_python程序的三种控制结构

    程序的三种控制结构 什么是控制结构 程序有三种基本结构组成 顺序结构 分支结构 循环结构 任何程序都是由这三种基本结构组成 顺序结构是程序按照线性顺序依次执行的一种运行方式 分支结构是程序根据条件判断结果而选择不同向前执行路径的一种运行方式
  • vue3 子组件向父组件传递参数

    1 父传子 父组件 在子组件上通过 v bind绑定属性 子组件 先定义下基本类型 然后通过setup的第一个参数取获取传过来的值 2 子传父 父组件 在子组件上绑定一个事件 并定义回调 子组件 通过setup的第二个参数去接受 第二个参数
  • 【Qt学习】08:文件读写操作

    OVERVIEW 文件读写操作 一 文件操作 1 QFile 2 QFileInfo 二 二进制文件读写 三 文本文件读写 文件读写操作 文件操作是应用程序必不可少的部分 Qt 作为一个通用开发库提供了跨平台的文件操作能力 Qt 通过QIO