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

news2024/9/28 7:15:46

OVERVIEW

  • 文件读写操作
      • 一、文件操作
        • 1.QFile
        • 2.QFileInfo
      • 二、二进制文件读写
      • 三、文本文件读写

文件读写操作


文件操作是应用程序必不可少的部分,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"); 这样的函数进行设置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/934081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web自动化测试之图文验证码的解决方案

对于web应用程序来讲&#xff0c;处于安全性考虑&#xff0c;在登录的时候&#xff0c;都会设置验证码&#xff0c; 验证码的类型种类繁多&#xff0c;有图片中辨别数字字母的&#xff0c;有点击图片中指定的文字的&#xff0c;也有算术计算结果的&#xff0c;再复杂一点就是滑…

电子封条监控系统 yolov5

电子封条监控系统利用yoloov5python 深度学习训练模型技术&#xff0c;电子封条监控系统实现对画面内外的出入人员、人数变化及非煤矿山生产作业状态等情况的实时监测和分析&#xff0c;及时发现异常动态&#xff0c;减少了人为介入的过程。介绍Yolo算法之前&#xff0c;首先先…

Android开发之性能测试工具Profiler

前言 性能优化问题&#xff0c;在我们开发时都会遇到&#xff0c;但是在小厂和对自己要求不严格的情况下&#xff0c;我都很少去做性能优化&#xff1b; 在性能优化上&#xff0c;基本大家都是通过自己的开发经验和性能分析工具来发现问题&#xff0c;今天给大家分享一下小编最…

性能优化之分库分表

1、什么是分库分表 1.1、分表 将同一个库中的一张表&#xff08;比如SPU表&#xff09;按某种方式&#xff08;垂直拆分、水平拆分&#xff09;拆分成SPU1、SPU2、SPU3、SPU4…等若干张表&#xff0c;如下图所示&#xff1a; 1.2、分库 在表数据不变的情况下&#xff0c;对…

【GeoDa实用技巧100例】025:geoda空间回归分析案例教程

严重声明:本文来自专栏《GeoDa空间计量案例教程100例》,为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:https://blog.csdn.net/lucky51222/category_12373659.html,谢绝转载或爬取!!! 文章目录 一、空间自回归模型二、Geoda空间回归分析普通最小二乘法回归(OLS)空间…

设计模式--建造者模式(Builder Pattern)

一、什么是建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它关注如何按照一定的步骤和规则创建复杂对象。建造者模式的主要目的是将一个复杂对象的构建过程与其表示分离&#xff0c;从而使同样的构建过程可以创建不同的表示。…

基于配置类方式管理 Bean

目录 一、完全注解开发理解 二、配置类和扫描注解 三、Bean定义组件 四、Bean注解细节 五、import 扩展 一、完全注解开发理解 Spring 完全注解配置&#xff08;Fully Annotation-based Configuration&#xff09;是指通过 Java配置类 代码来配置 Spring 应用程序&#…

Folyd 多源最短路

目录 简介 实现 代码 关于Floyd的题目 简介 首先我们要知道a到b的最短路是什么 a到b的最短路是从a点到b点的最小距离&#xff08;花费&#xff09; 那多源最短路呢就是能求任意a和b&#xff0c;之间的最短路 那么Folyd是多源最短路&#xff0c;也就是求任意a和b&#x…

春秋云镜 CVE-2019-13275

春秋云镜 CVE-2019-13275 WordPress Plugin wp-statics SQLI 靶标介绍 WordPress VeronaLabs wp-statistics插件12.6.7之前版本中的v1/hit端点存在SQL注入漏洞。 启动场景 漏洞利用 exp time curl -X POST http://host/wp-json/wpstatistics/v1/hit --data "wp_stati…

SpringBoot权限认证

SpringBoot的安全 常用框架&#xff1a;Shrio,SpringSecurity 两个功能&#xff1a; Authentication 认证Authorization 授权 权限&#xff1a; 功能权限访问权限菜单权限 原来用拦截器、过滤器来做&#xff0c;代码较多。现在用框架。 SpringSecurity 只要引入就可以使…

mybatis:动态sql【2】+转义符+缓存

目录 一、动态sql 1.set、if 2.foreach 二、转义符 三、缓存cache 1. 一级缓存 2. 二级缓存 一、动态sql 1.set、if 在update语句中使用set标签&#xff0c;动态更新set后的sql语句&#xff0c;&#xff0c;if作为判断条件。 <update id"updateStuent" pa…

【C++】容器适配器stack、queue以及deque容器

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;C的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录 前言一、什么是容器适配器1.1 stack的…

开源软件的漏洞响应:应对安全威胁

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

岛屿数量00

题目链接 岛屿数量 题目描述 注意点 grid[i][j] 的值为 ‘0’ 或 ‘1’ 解答思路 使用广度优先遍历思想遍历整个岛屿遍历整个二维网络&#xff0c;如果此时位置处的值为1&#xff0c;则当前位置是一个岛的一部分&#xff0c;从该位置向着四个方向遍历出整个岛屿&#xff0…

【滑动窗口】leetcode3:无重复字符的最长子串

一.题目描述 无重复字符的最长子串 二.思路分析 题目要求我们找符合要求的最长子串&#xff0c;要求是不能包含重复字符 确定一个子串只需确定它的左右区间即可&#xff0c;于是我们可以两层循环暴力枚举所有的子串&#xff0c;找到符合要求的&#xff0c;并通过比较得到最长…

5G+智慧交通行业解决方案[46页PPT]

导读&#xff1a;原文《5G智慧交通行业解决方案[46页PPT]》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 喜欢文章&#xff0c;您可以点赞评论转发本文&#xff0c;…

基于Java+SpringBoot+Vue前后端分离贸易行业crm系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

小研究 - JVM 逃逸技术与 JRE 漏洞挖掘研究(七)

Java语言是最为流行的面向对象编程语言之一&#xff0c; Java运行时环境&#xff08;JRE&#xff09;拥有着非常大的用户群&#xff0c;其安全问题十分重要。近年来&#xff0c;由JRE漏洞引发的JVM逃逸攻击事件不断增多&#xff0c;对个人计算机安全造成了极大的威胁。研究JRE安…

小研究 - Java虚拟机内存管理分析

讨论了&#xff2a;&#xff41;&#xff56;&#xff41;关键技术组成&#xff0c;深入介绍了&#xff2a;&#xff41;&#xff56;&#xff41;虚拟机的体系结构&#xff0c;分析了虚拟机中内存管理的垃圾回收机制。同时&#xff0c;对现有的一些流行垃圾回收算法进行了深入…

5年经验之谈 —— APP和WEB的测试区别

在功能测试时&#xff0c;要考虑手机应用的特性&#xff1a; 1&#xff09;手机屏幕尺寸偏小&#xff0c;所以手机应用一般就占满了全屏&#xff0c;因此要考虑手机在前后端切换时被测试应用在资源使用时的优先级变化情况&#xff1b;还要考虑手机横竖屏切换时的测试 2&#xf…