2.文件操作
①输入输出设备类
在Qt中,文件读写的类为QFile
。QFile
的父类为QFileDevice
,QFileDevice
提供了文件交互操作的底层功能。QFileDevice
的父类是QIODevice
,QIODevice
的父类为QObject
。
QIODevice
是Qt中所有输入输出设备(input/output device
,简称I/O设备)的基础类,I/O设备就是能进行数据输入和输出的设备,例如文件是一种I/O设备,网络通信中的socket是I/O设备,串口、蓝牙等通信接口也是I/O设备,所以它们也是从QIODevice
继承来的。
Qt中主要的一些I/O设备类的继承关系如下图所示:
上图中各类的说明如下:
QFile
是用于文件操作和文件数据读写的类,使用QFile
可以读写任意格式的文件。QSaveFile
是用于安全保存文件的类。使用QSaveFile
保存文件时,它会先把数据写入一个临时文件,成功提交后才将数据写入最终的文件。如果保存过程中出现错误,临时文件里的数据不会被写入最终文件,这样就能确保最终文件中不会丢失数据或被写入部分数据。在保存比较大的文件或复杂格式的文件时可以使用这个类,例如从网络上下载文件等。QTemporaryFile
是用于创建临时文件的类。使用函数QTemporaryFile:open()
就能创建一个文件名唯一的临时文件,在QTemporaryFile
对象被删除时,临时文件被自动删除。QTcpSocket
和QUdpSocket
是分别实现了TCP和UDP
的类。QSerialPort
是实现了串口通信的类,通过这个类可以实现计算机与串口设备的通信。QBluetoothSocket
是用于蓝牙通信的类。手机和平板计算机等移动设备有蓝牙通信模块,笔记本电脑一般也有蓝牙通信模块。通过QBluetoothSocket
类,就可以编写蓝牙通信程。如编程实现笔记本电脑与手机的蓝牙通信。QProcess
类用于启动外部程序,并且可以给程序传递参数。QBuffer
以一个QByteArray
对象作为数据缓冲区,将QByteArray
对象当作一个I/O设备
来读写。
②文件读写类
在Qt中,文件的读写主要是通过QFile类来实现。在QFile类中提供了一些用来读写文件的方法。对于文件的操作主要有:
- 读数据:QFile类中提供了多个方法用于读取文件内容;如read()、readAll()、readLine()等。
- 写数据:QFile类中提供了多个方法用于往文件中写内容;如write(0、writeData(O等。
- 关闭文件:文件使用结束后必须用函数close(0关闭文件。
访问一个设备之前,需要使用open()函数打开该设备,而且必须指定正确的打开模式,QIODevice
中所有的打开模式由QIODevice::OpenMode
枚举变量定义,其取值如下:
QIODevice:NotOpen | 没有打开设备 |
QIODevice::ReadOnly | 以只读方式打开设备 |
QIODevice::WriteOnly | 以只写方式打开设备 |
QIODevice::ReadWrite | 以读写方式打开设备 |
QIODevice::Append | 以追加方式打开设备,数据将写到文件末未尾 |
QIODevice:Truncate | 每次打开文件后重写文件内容,原内容将被删除 |
QIODevice::Text | 在读文件时,行尾终止符会被转换为';当写入文件时,行尾终止符会被转换为本地编码。如Win32上为r\n'; |
QIODevice::Unbuffered | 无缓冲形式打开文件,绕过设备中的任何缓冲区 |
QIODevice::NewOnly | 文件存在则打开失败,不存在则创建文件 |
1>简单实现记事本的打开文件和保存文件功能
#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; // 全局定义,否则handle函数无法访问
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFileDialog>
#include<QDebug>
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(QIODevice::ReadOnly);
//判断是否成功打开文件
if(!ret)
{
statusbar->showMessage(path + "打开文件失败");
return;
}
//4.读取文件
QString text = file.readAll();
// 返回的是QByteArray,可以用QString来实现相互转换(QString运算符重载提供了相关API)
// 需要确保当前打开的文件是文本文件,如果是二进制文件就不合适
//5.关闭文件!很重要,不关闭可能造成内存泄漏
file.close();
//6.读到的内容设置到输入框
edit->setPlainText(text);
}
//保存
void MainWindow::handleAction2()
{
//1.先弹出“保存文件”对话框,让用户选择打开哪个文件,这次使用的是getSaveFileName
QString path = QFileDialog::getSaveFileName(this);
//2.把文件名显示到状态栏里
QStatusBar* statusbar = this->statusBar();
statusbar->showMessage(path);
//3.根据用户选择路径,构造一个QFile对象,并打开文件(写方式)
QFile file(path);
//bool ret = file.open(QIODevice::WriteOnly);
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();
}
③文件和目录信息类
QFilelnfo
是Qt提供的一个用于获取文件和目录信息的类,如获取文件名、文件大小、文件修改日期等。类似于这样的功能,在C/C++标准库中本来都没有,所以想使用类似的功能往往要使用系统api,不过在C++17引入了模块filesystem
QFilelnfo
类中提供了很多的方法,常用的有
方法 | 说明 |
isDir() | 检查该文件是否是目录 |
siExecutable() | 检查该文件是否是可执行文件 |
fileName() | 获得文件名 |
comp;eteBaseName() | 获取完整的文件名 |
suffix() | 获取完整的文件后缀 |
size() | 获取文件大小 |
isFile() | 判断是否为文件 |
fileTime() | 获取文件创建时间、修改时间、最近访问时间等 |
1>打印文件的属性信息
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<QFileInfo>
#include<QFileDialog>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
//弹出文件对话框并获取文件属性信息
QString path = QFileDialog::getOpenFileName(this);
//构造出一个QFileInfo对象
QFileInfo fileInfo(path);
//打印信息
qDebug() << fileInfo.fileName();
qDebug() << fileInfo.suffix();
qDebug() << fileInfo.path();
qDebug() << fileInfo.size();
qDebug() << fileInfo.isFile();
qDebug() << fileInfo.isDir();
}