阅读导航
- 引言
- 一、Qt文件概述
- 二、输入输出设备类
- 三、文件读写类
- 四、文件和目录信息类
- 五、自定义“记事本”
引言
在上一篇文章中,我们学习了Qt的事件处理机制,知道了如何响应用户的操作。但应用程序常常还需要处理文件,比如读写数据。所以,接下来的文章,我们将介绍Qt的文件操作功能,包括如何打开、保存、读取和写入文件等。掌握了这些,您的应用程序就能更好地处理数据了。让我们一起学习吧!
一、Qt文件概述
文件操作是任何应用程序都不可或缺的重要部分。Qt,作为一个功能强大的跨平台开发框架,为开发者提供了丰富的文件操作接口和类。通过这些类,开发者可以轻松实现对文件系统的各种操作,包括但不限于文件的读写、文件信息的获取、文件的复制、重命名以及更复杂的文件管理任务。Qt的跨平台特性确保了无论在哪种操作系统上,文件操作都能保持一致性和高效性。
二、输入输出设备类
在Qt框架中,处理文件读写操作的核心类是QFile
。QFile
类继承自QFileDevice
,后者为文件交互操作提供了底层的支持功能。进一步追溯,QFileDevice
的基类是QIODevice
,这个类在Qt中扮演着至关重要的角色,作为所有输入/输出(I/O)设备的基础。I/O设备指的是能够执行数据输入和输出操作的任何设备,包括但不限于文件、网络通信中的socket、串口、蓝牙等通信接口。
QIODevice
类为Qt中的I/O操作提供了一个统一的接口,使得无论是文件操作、网络通信还是其他形式的I/O操作,都可以通过相似的API来实现。因此,Qt中许多与I/O相关的类,如处理文件、网络通信、串口通信等的类,都是从QIODevice
直接或间接继承而来的。这种设计使得Qt的I/O系统既灵活又强大,能够支持多种不同的I/O场景。
简而言之,Qt通过QFile
、QFileDevice
和QIODevice
等类构建了一个强大的I/O系统,其中QFile
专门用于文件读写,而QIODevice
则是所有I/O设备类的基类,为Qt的I/O操作提供了统一的基础。
三、文件读写类
在Qt框架中,文件的读写操作主要依赖于QFile
类。QFile
类提供了一系列的方法用于处理文件的读写操作,包括但不限于以下几种:
- 读数据:为了从文件中读取数据,
QFile
类提供了多个方法,如read()
、readAll()
和readLine()
等。这些方法允许开发者根据需要读取文件内容的不同部分。 - 写数据:向文件中写入内容同样可以通过
QFile
类实现,提供了如write()
和writeData()
等方法。这些方法允许开发者将字符串、字节数组等数据写入到文件中。 - 关闭文件:在完成文件操作后,为了释放系统资源,应该使用
close()
方法关闭文件。这是一个良好的编程习惯,可以避免资源泄露等问题。
在进行文件读写之前,必须先使用open()
方法打开文件,并指定正确的打开模式。这些打开模式由QIODevice::OpenMode
枚举变量定义,包括只读、只写、追加等多种模式,以满足不同的文件操作需求。其取值如下:
下面是将上述QIODevice::OpenMode
枚举值列成表格:
枚举值 | 描述 |
---|---|
QIODevice::NotOpen | 没有打开设备 |
QIODevice::ReadOnly | 以只读方式打开设备 |
QIODevice::WriteOnly | 以只写方式打开设备 |
QIODevice::ReadWrite | 以读写方式打开设备 |
QIODevice::Append | 以追加方式打开设备,数据将写到文件末尾 |
QIODevice::Truncate | 每次打开文件后重写文件内容,原内容将被删除 |
QIODevice::Text | 在读文件时,行尾终止符会被转换为’\n’;当写入文件时,行尾终止符会被转换为本地编码(如Win32上为’\r\n’) |
QIODevice::Unbuffered | 无缓冲形式打开文件,绕过设备中的任何缓冲区 |
QIODevice::NewOnly | 文件存在则打开失败,不存在则创建文件 |
🚨🚨注意:QIODevice::OpenMode
是一个标志,这意味着它可以通过位或操作符(|
)组合多个模式。例如,如果你想要以读写和追加模式打开文件,你可以使用QIODevice::ReadWrite | QIODevice::Append
。
四、文件和目录信息类
QFileInfo
是 Qt 框架中提供的一个非常实用的类,它允许开发者获取关于文件和目录的详细信息。通过这个类,可以轻松地查询文件的名称、大小、修改日期等关键属性。QFileInfo
提供了丰富的方法,以满足不同的查询需求。
isDir()
:此方法用于检查指定的路径是否代表一个目录。isExecutable()
:此方法用于判断文件是否是一个可执行文件。这通常取决于文件的权限和属性。fileName()
:此方法返回文件的名称(不包括路径)。completeBaseName()
:与fileName()
类似,但在某些情况下,如果文件名包含前缀(如版本号),completeBaseName()
可能会返回更完整的文件名基础部分,具体行为可能依赖于平台和文件命名约定。suffix()
:此方法返回文件的扩展名(后缀),即文件名中最后一个点(.
)之后的部分。completeSuffix()
:与suffix()
相比,这个方法可能用于处理更复杂的文件名,返回完整的后缀,包括可能的多个点分隔的部分。但请注意,Qt 的标准QFileInfo
类通常只提供suffix()
方法,completeSuffix()
可能指的是特定上下文或Qt版本中的扩展功能。size()
:此方法返回文件的大小,以字节为单位。isFile()
:此方法用于判断给定的路径是否确实指向一个文件(而不是目录或其他类型的文件系统条目)。fileTime()
:获取文件创建时间、修改时间、最近访问时间等
五、自定义“记事本”
⭕mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPlainTextEdit>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void handleAction1();
void handleAction2();
private:
Ui::MainWindow *ui;
QPlainTextEdit* edit;
};
#endif // MAINWINDOW_H
⭕mainwindow.cpp
#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();
// 添加菜单
QMenu* menu = new QMenu("文件");
menuBar->addMenu(menu);
// 添加菜单项
QAction* action1 = new QAction("打开");
QAction* action2 = new QAction("保存");
menu->addAction(action1);
menu->addAction(action2);
// 指定一个输入框.
edit = new QPlainTextEdit();
QFont font;
font.setPixelSize(20);
edit->setFont(font);
this->setCentralWidget(edit);
// 连接 QAction 的信号槽.
connect(action1, &QAction::triggered, this, &MainWindow::handleAction1);
connect(action2, &QAction::triggered, this, &MainWindow::handleAction2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handleAction1()
{
// 1. 先弹出 "打开文件" 对话框. 让用户选择打开哪个文件.
QString path = QFileDialog::getOpenFileName(this);
// 2. 把文件名显示到状态栏里.
QStatusBar* statusBar = this->statusBar();
statusBar->showMessage(path);
// 3. 根据用户选择的路径, 构造一个 QFile 对象. 并打开文件
QFile file(path);
bool ret = file.open(QFile::ReadOnly);
if (!ret) {
// 打开文件失败!
statusBar->showMessage(path + " 打开失败!");
return;
}
// 4. 读取文件了.
QString text = file.readAll();
// 5. 关闭文件!! 千万不要忘记!!
file.close();
// 6. 读到的内容设置到输入框中.
edit->setPlainText(text);
}
void MainWindow::handleAction2()
{
// 1. 先弹出 "保存文件" 对话框.
QString path = QFileDialog::getSaveFileName(this);
// 2. 在状态栏中显示这个文件名.
QStatusBar* statusBar = this->statusBar();
statusBar->showMessage(path);
// 3. 根据用户选择的路径, 构造一个 QFile 对象, 并打开文件.
QFile file(path);
bool ret = file.open(QFile::WriteOnly);
if (!ret) {
statusBar->showMessage(path + " 打开失败!");
return;
}
// 4. 写文件.
const QString& text = edit->toPlainText();
file.write(text.toUtf8());
// 5. 关闭文件.
file.close();
}
⭕运行效果