[Qt]系统相关-文件操作-QFile、QFileInfo类以及相关操作函数
目录
一、Qt文件系统
1.Qt文件系统的介绍
2.Qt文件类
二、Qt文件的操作
1.文件的打开
2.文件的读写操作
3.关闭操作
4.接口使用案例
5.获取文件的相关属性
三、文件的分类
1.文本文件
2.二进制文件
3.二者的区别
一、Qt文件系统
1.Qt文件系统的介绍
文件操作是所有开发程序和开发语言必不可少的一个重要的部分,无论是C/C++、还是系统级别操作等提供了一套完整的文件操作接口,Qt作为了一个通用开发库,也必须提供了跨平台的文件操作能力。Qt中提供了很多文件的类,通过这些类能够对文件系统进行快速的操作了。
| C语言标准库 | C++标准库 | Linux系统调用 | |
| 打开文件 | fopen函数 | fstream类 | open函数 |
| 读取文件 | fread函数 | operator<<成员函数 | read函数 |
| 写入文件 | fwrite函数 | operator>>()成员函数 | write函数 |
| 关闭文件 | fclose函数 | close成员函数 | close函数 |
而且Windows系统下,也会有Windows的一套系统调用接口去进行文件操作,那么不管是不同平台下,还是语言层面都有很多对文件的操作,为什么Qt还要自己去弄一套自己的文件操作呢?因为Qt的诞生节点有关,诞生的时候,C++还有没完整的标准化概念,所以Qt自己弄了一套方案。再编写Qt程序的时候,更推荐Qt自己提供的一套文件操作,因为QString等Qt自己的类和自己的文件操作配合会更方便一些。当然也可以使用上述的其他体系去实现文件操作。
2.Qt文件类
在Qt中的文件操作中核心的无非也就是打开文件、读写文件和关闭文件的操作。Qt提供了一个QFile类,该类就可以实现上述的操作和对文件的管理。OFile类继承自OFileDevice类,该类中就提供了文件交互操作的底层功能。QFileDevice类的父亲是QIODevice,QIODevice的父亲就是所有类的祖先QObject类。

QIODevice类是Qt中所有的输入输出设备的基础类,磁盘文件、网络通信的Socket套接字、串口、蓝牙等等都是属于输入输出型设备,所以都是继承于QIODevice类。
| 类名 | 介绍 |
| QFile | 用于文件操作和文件读写的类 |
| QSaveFile | 用于安全保存文件的类,使用该类对象保存文件的时候,会先将数据写入一个临时文件,成功提交折后才会将数据写入最终的文件当中,如果保存过程中有错误的话,临死文件的内容不会写入最终文件,保证最终文件中不会出现数据残缺或丢失的问题,也就是说如果写入失败也会保留原有的数据。在保存比较大型的文件或者复杂格式的文件可以使用这个类。 |
| QTemporaryFile | 用于创建临时文件的类,可以创建出一个唯一的临时文件,该QTemporaryFile对象销毁的时候,临时文件也就销毁了 |
| QTcpSocket、QUdpSocket | 实现了TCP和UDP通信的类 |
| QSerialPort | 实现了串口通信的类,通过该类可以实现计算机与串口设备的通信。串口是一个比较老的通信方式,一般是在嵌入式系统上用的较多。 |
| QBluetoochSocket | 用于蓝牙通信的类 |
| QPrecess | 用于启动外部程序的类,可以给程序传递参数内容。相当于fork、exec操作的封装。 |
| QBuffer | 是以一个QByteArray对象作为缓冲区,对这个缓冲区进行I/O操作的类。相当于一个缓冲区类 |
二、Qt文件的操作
1.文件的打开
QFile::QFile(const QString &name); //创建QFile对象
virtual bool open(QIODevice::OpenMode mode) override; //打开文件
Qt中打开文件之前是需要创建一个QFile对象的并传递一个文件路径,之后配合着QFile类内部的open函数进行打开文件。open打开文件的函数传递的参数是文件的打开方式,也就是读方式、写方式、追加写等等方式,不用传递文件路径了,因为QFile对象内部已经记录了管理的文件所在的路径了。OpenMode是一个枚举类型,枚举出了一些打开文件的方式。

QFile类中也提供了其他的open函数,但是没有上述的方便。需要传递C语言标准库中的文件对象FILE或者底层的文件描述符。
bool open(FILE *fh, QIODevice::OpenMode mode,
QFileDevice::FileHandleFlags handleFlags = DontCloseHandle);bool open(int fd, QIODevice::OpenMode mode,
QFileDevice::FileHandleFlags handleFlags = DontCloseHandle);
2.文件的读写操作
读取操作函数
// 尽可能的读取文件内容
qint64 read(char* data, qint64 maxSize);
QByteArray read(qint64 maxSize);
// 一次性将文件内容都读取出来
QByteArray readAll();
// 读取一行数据
qin64 readLine(char* data, qint64 maxSize);
QByteArray readLine(qint64 maxSize = 0);
QByteArray返回值是一个字符数组,是Qt对于字符数组的封装,QString类中重载了operator =函数可以传递该QByteArray参数,所以很容易就可以转化为QString类型的字符串了。但是前提是打开的文件一个文本文件,如果是二进制文件的话,就会出现一些问题了。
写入操作函数
qint64 write(const char* data, qint64 maxSize);
qint64 write(const char* data);
qint64 write(const QByteArray& byteArray);
3.关闭操作
virtual void close();
一定要在操作文件之后关闭文件,从底层来说,系统的文件描述符表有上限,一直运行的程序如果不关闭的话,文件描述符越开越多,就会占满文件描述符表了,就会出问题。而且每一个文件描述符都会关联一个strutc file,系统也要将这些struct file结构体维护起来。还有就是如果不关闭的话,文件就会一直处于打开状态,在内存中,系统还要维护这些打开的文件。所以说文件操作完毕之后一定要关闭文件。
4.接口使用案例
案例:实现打开文件和保存文件的操作。
该案例是模拟了一个记事本的操作,在菜单栏中提供了打开文件和保存文件的操作,打开文件关联的槽函数是,将指定路径文件的内容读取出来放入到多行输入文本框中,保存文件关联的槽函数是,将文本框中的内容写入到指定路径的文件当中。
在保存文件的时候,需要QStrin的字符串文本类型重写转化为QByteArray类型,Qt中也提供了很多的转换函数。这里我们发现会有很多种转换的函数,而且需要我们自己手动转化,这是为什么呢?QByteArray存放的是我们打开的文件,存储的内容原始字节表示形式。而QString字符串是根据特定的编码格式将原始字节数据转化为了特定的文本格式了。
当QByteArray转化为QStirng的时候,默认是使用utf8编码方式进行转化。当然如果我们想要 转化为其他形式的话,也是需要使用Qt内置的一些接口进行转换的。当然前提是该文本类型不是二进制类型,否则二进制类型文件转化后会成一堆乱码。在打开文件的时候,一般都是打开的文本文件,所以默认使用的utf8的转换方式。而QString转化为QByteArray的时候,系统不知道我们想要保存的文件是什么类型,而且存放二进制文件和文本文件的几率基本上是一样的。所以说没有设置默认的存储类型,而是需要我们自己去设置。
QString转换QByteArray函数

const QString text = edit->toPlainText();
file.write(text.toUtf8());
QByteArray转换QString函数
QByteArray latin1Array = "Hello, World";
QString str2 = QString::fromLatin1(latin1Array);QByteArray local8BitArray = "Hello, 世界";
QString str3 = QString::fromLocal8Bit(local8BitArray);
案例代码
//edit是一个QTextEdit类型的成员函数,定义在mainwindow.h文件当中#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//修改窗口标题this->setWindowTitle("记事本");//创建菜单栏QMenuBar* menubar = this->menuBar();this->setMenuBar(menubar);//添加菜单QMenu* menu = new QMenu("文件");menubar->addMenu(menu);//添加菜单项QAction* action1 = new QAction("打开文件");QAction* action2 = new QAction("保存文件");menu->addAction(action1);menu->addAction(action2);//创建一个输入框edit = new QTextEdit();//设置输入框的字体QFont font;font.setPixelSize(20);edit->setFont(font);//将窗口的中心部件设置为多行输入框this->setCentralWidget(edit);//将菜单项绑定槽函数connect(action1, &QAction::triggered, this, &MainWindow::openfile);connect(action2, &QAction::triggered, this, &MainWindow::savefile);
}MainWindow::~MainWindow()
{delete ui;
}//打开文件
void MainWindow::openfile()
{// 首先弹出一个选择文件的对话框QString path = QFileDialog::getOpenFileName(this);// 把选择的文件名显示到状态栏里面QStatusBar* statusbar = this->statusBar();statusbar->showMessage(path);//根据用户选择的路径,打开文件QFile file(path);bool ret = file.open(QIODevice::ReadOnly);if(ret == false){statusbar->showMessage(path + "打开失败");return;}//读取文件写入输入框QString text = file.readAll();//关闭文件file.close();//把读取的文件内容写入到输入框中。edit->setText(text);
}//保存文件
void MainWindow::savefile()
{//弹出一个保存文件对话框,选择保存的路径QString path = QFileDialog::getSaveFileName(this);//在状态栏中显示文件名QStatusBar* statusbar = this->statusBar();statusbar->showMessage(path);//根据选择的路径构造一个QFile对象,并打开文件QFile file(path);bool ret = file.open(QIODevice::WriteOnly);if(ret == false){statusbar->showMessage("保存失败");return;}//获取输入框的内容const QString text = edit->toPlainText();//写入到文件当中file.write(text.toUtf8());//关闭文件file.close();
}

5.获取文件的相关属性
在Qt当中FileInfo类可以获取到Qt文件的相关属性。对于该操作在C/C++标准库中先前是没有相关此操作的,如果我们想要获得文件的属性就需要进系统调用进行获取,直到C++17才引入了相关的模块,提供了此功能。所以Qt就自己设计了一套获取文件相关属性的操作。
使用案例
void Widget::on_pushButton_clicked()
{//弹出对话框,选择文件并获取文件信息QString path = QFileDialog::getOpenFileName(this);//构造QFileInfo对象QFileInfo fileinfo(path);ui->textEdit->append("文件名: " + fileinfo.fileName());ui->textEdit->append("文件后缀: " + fileinfo.suffix());ui->textEdit->append("文件路径: " + fileinfo.path());ui->textEdit->append("文件大小: " + QString::number(fileinfo.size()));ui->textEdit->append("文件类型是否是普通文件: " + QString(fileinfo.isFile() == true ? "是" : "不是"));ui->textEdit->append("文件类似是否是一个目录: " + QString(fileinfo.isDir() == true ? "是" : "不是"));
}
更多的QFileInfo内置的函数以及使用可以查看帮助文档。
三、文件的分类
1.文本文件
文本文件是由字符序列组成的文件内容,通常包含的是人类可以看懂的文本内容。这些字符按照一定的编码方式进行存储(UTF8、ASCII等),每个字符占用一个或者多个字节。其实这些字符底层也一定是一堆二进制数字,但是通过特定的编码,每个字符都会对应一个特定的二进制序列,会将这些二进制数据和我们能看懂的字符进行相互转化。
文本文件常用于存储配置信息、源代码、日志文件、CSV 文件等。例如,配置文件.ini通常存储键值对,如key=value的形式;CSV 文件存储表格数据,以逗号分隔不同的字段。
2.二进制文件
二进制文件存储的就是原始的二进制数据了,不是字符序列,大多数都是一些图像、视频和音频数据、数据库文件以及可执行文件等内容。这些数据不是并没有经过特定的编码格式排列,所以说并非是我们可以看懂的。通过一些特定的编码方式进行转化的话,转化后的也是一些乱码的字符数据。
3.二者的区别
- 可读性:文本文件是给人类读的,所以可读性一定是很好的,而二进制文件的话,通常是给计算机看的,计算机会解析成一些图片、音频或者执行一些程序。
- 存储效率:存储效率来说的话,文本文件的存储时,需要根据使用的编码方式进行特定格式的存储,而且一个文字可能会占用多个字节,例如UTF8中一个英文字符占用一个字节,而对于一些汉字来说要占用多个。而二进制文件的存储来说,不会进行字符编码,直接存储原始数据即可,存储效率比较高。对于一些需要存储大量数据的场景,如存储音频样本或图像像素,使用二进制文件可以更紧凑地存储数据,避免了字符编码的额外开销。但也并非绝对的,例如存储一个数字900,对于文本文件来说就是3个字符是3个字节,而对于二进制来说就是一个int类型的数字,需要4个字节了。
- 跨平台性:文本文件在不同的操作系统下,换行符是不同的,在Windows上是\r\n,而linux下确实\n,所以可能会导致在跨平台处理文本文件的时候,需要进行换行字符的转化。而二进制文件来说虽然不受字符编码和换行符的影响,但是不同平台下可能对于数据的存储个数有不同的处理方式,例如大小端模式的区别。不同平台存储多字节数据的字节顺序可能不同,因此在跨平台使用二进制文件时,可能需要进行字节序的转换或其他数据格式的调整。
相关文章:
[Qt]系统相关-文件操作-QFile、QFileInfo类以及相关操作函数
目录 一、Qt文件系统 1.Qt文件系统的介绍 2.Qt文件类 二、Qt文件的操作 1.文件的打开 2.文件的读写操作 3.关闭操作 4.接口使用案例 5.获取文件的相关属性 三、文件的分类 1.文本文件 2.二进制文件 3.二者的区别 一、Qt文件系统 1.Qt文件系统的介绍 文件操作是所…...
C#高级:用Csharp操作鼠标和键盘
一、winform 1.实时获取鼠标位置 public Form1() {InitializeComponent();InitialTime(); }private void InitialTime() {// 初始化 Timer 控件var timer new System.Windows.Forms.Timer();timer.Interval 100; // 设置为 100 毫秒,即每 0.1 秒更新一次timer.…...
Mac 使用 GVM 管理多版本 Go 环境
使用 GVM 管理多版本 Go 环境 在本文中,我们将使用 gvm(Go Version Manager)工具管理本地多个 Go 语言版本。gvm 功能类似于 Python 的 Anaconda,可以方便地切换不同版本的 Go 环境,非常适合需要多版本开发与测试的场…...
25届合肥工业大学自动化考研复试攻略
本文内容,全部选自联盟自动化考研联盟企业店的:《合肥工业大学控制综合笔试篇》。后续会持续更新更多内容,记得关注哦~ 目录 Part1:复试指南具体内容 Part2:复试复习相关介绍 Part1:复试指南具体内容 1…...
【24】Word:小郑-准考证❗
目录 题目 准考证.docx 邮件合并-指定考生生成准考证 Word.docx 表格内容居中表格整体相较于页面居中 考试时一定要做一问保存一问❗ 题目 准考证.docx 插入→表格→将文本转换成表格→✔制表符→确定选中第一列→单击右键→在第一列的右侧插入列→布局→合并单元格&#…...
前瞻2024:前沿技术的全景洞察与深度剖析
在当今时代,前沿技术以前所未有的速度发展,深刻地改变着我们的生活、工作和社会的各个层面。从人工智能的迅猛发展到量子计算的逐步突破,从生物技术的不断创新到新能源技术的广泛应用,这些前沿技术正成为推动社会进步和经济发展的…...
告别手动编辑:如何用Python快速创建Ansible hosts文件?
在自动化运维领域,Ansible是一款非常强大的工具,它可以帮助我们管理和配置大量的服务器。为了让Ansible能够有效地管理这些服务器,我们需要一个hosts清单文件,该文件定义了Ansible要管理的目标主机。在实际应用中,我们…...
ESP32云开发二( http + led + lcd)
文章目录 前言先上效果图platformio.iniwokwi.tomldiagram.json源代码编译编译成功上传云端完结撒花⭐⭐⭐⭐⭐ 前言 阅读此篇前建议先看 此片熟悉下wokwi https://blog.csdn.net/qq_20330595/article/details/144289986 先上效果图 Column 1Column 2 platformio.ini wokwi…...
Java 基于微信小程序的原创音乐小程序设计与实现(附源码,部署,文档)
大家好,我是stormjun,今天为大家带来的是Java实战项目-基于微信小程序的原创音乐小程序设计与实现。该系统采用 Java 语言 开发,MySql 作为数据库,系统功能完善 ,实用性强 ,可供大学生实战项目参考使用。 博…...
JavaWeb开发(十五)实战-生鲜后台管理系统(二)注册、登录、记住密码
1. 生鲜后台管理系统-注册功能 1.1. 注册功能 (1)创建注册RegisterServlet,接收form表单中的参数。 (2)service创建一个userService处理业务逻辑。 (3)RegisterServlet将参数传递给ser…...
在stm32中C语言编写的程序中,一个整形数据是怎么存储的,高位在前还是低位在前
目录 举个例子 如何验证 小结 在 STM32(基于 ARM Cortex-M 架构)的系统中,默认是小端(Little Endian) 存储方式。也就是说,对于一个整型(例如 32 位 int),它的最低有效…...
Redis系列之底层数据结构字典Dict
Redis系列之底层数据结构字典Dict Dict数据结构 Dict是Redis数据结构中使用最为频繁的复合型数据结构,本质上是一个哈希表 查看redis6.0版本的源码,链接:https://github.com/redis/redis/blob/6.0/src/dict.h 哈希表的结构定义࿱…...
CSS 溢出问题及解决方案:实用案例与技巧
在网页开发中,CSS 的布局和样式起着至关重要的作用,但经常会遇到一个棘手的问题——溢出问题。溢出是指元素内的内容超出了其设定的容器大小,这不仅会影响页面的美观,还可能干扰用户体验。本文将详细探讨 CSS 溢出问题的案例&…...
FastExcel 新一代的潮流 (EasyExcel)
目录 简介 FastExcel的特点 FastExcel使用方法详解 创建实体类和监听器 实现写入和读取功能 Excel转换为PDF 小结 FastExcel与EasyExcel的区别 结论 简介 FastExcel是由原EasyExcel作者在阿里巴巴宣布停止维护EasyExcel之后推出的升级版框架。它继承了EasyExcel的所有…...
使用ffmpeg提高mp4压缩比,减小文件体积【windows+ffmpeg+batch脚本】
文章目录 关于前情提要FFmpeg是什么使用脚本运行FFmpeg首先,下载ffmpeg.exe然后在视频相同位置写一个bat脚本运行压缩脚本 关于 个人博客,里面偶尔更新,最近比较忙。发一些总结的帖子和思考。 江湖有缘相见🤝。如果读者想和我交…...
cuda从零开始手搓PB神经网络
cuda实现PB神经网络 基于上一篇的矩阵点乘,实现了矩阵的加减乘除、函数调用等。并且复用之前元编程里面写的梯度下降、Adam、NAdam优化方法。实现PB神经网络如下: #ifndef __BP_NETWORK_HPP__ #define __BP_NETWORK_HPP__ #include "matrix.hpp&quo…...
mac 安装mongodb
本文分享2种mac本地安装mongodb的方法,一种是通过homebrew安装,一种是通过tar包安装 homebrew安装 brew tap mongodb/brew brew upate brew install mongodb-community8.0tar包安装 安装mongodb 1.下载mongodb社区版的tar包 mongdb tar包下载地址 2…...
K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略
1. Pod资源清单的编写 1.1 Pod运行单个容器的资源清单 ##创建工作目录 mkdir -p /root/manifests/pods && cd /root/manifests/pods vim 01-nginx.yaml ##指定api版本 apiVersion: v1 ##指定资源类型 kind: Pod ##指定元数据 metadata:##指定名称name: myweb ##用户…...
【Maui】视图界面与数据模型绑定
文章目录 前言一、问题描述二、解决方案三、软件开发(源码)3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI&…...
JavaScript笔记基础篇02——运算符、语句、数组
黑马程序员视频地址:黑马程序员前端JavaScript入门到精通全套视频教程https://www.bilibili.com/video/BV1Y84y1L7Nn?vd_source0a2d366696f87e241adc64419bf12cab&spm_id_from333.788.videopod.episodes 目录 运算符 赋值运算符 编辑编辑 一元运算符…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
