QFile
QFile 是 Qt 框架中用于文件操作的类,提供了丰富的功能来读取、写入和操作文件。
使用时需包含头文件
cpp
#include <QFile>
#include <QTextStream>
QFile为文件操作的类
QTextStream为文本流类,用来绑定一个文本文件,可以更方便的读写文件
文件读写分为文本文件读写和二进制文件读写,
文本文件(text file,textfile,flatfile): 一般指只有字符原生编码构成的[二进制](https://www.bing.com/search?q=二进制 wikipedia&form=WIKIRE)计算机文件,能够被最简单的[文本编辑器](https://www.bing.com/search?q=文本编辑器 wikipedia&form=WIKIRE)直接读取。
常见的文本文件,cpp等源码文件,txt, doc, md, json以及大部分文本编辑器能直接读取的文件。
二进制文件: 以二进制方式存储的文件,除文本文件外,我们接触到的大部分都是二进制文件。
常见的二进制文件,exe可执行文件, jpeg,jpg等图片文件等。
我们先从文本文件读写开始介绍
定义文件
我们在打开文件之前,需要用QFile先指定一个文件
cpp
//用QFile绑定一个文件
QFile file("example.txt");
打开文本文件
可通过open函数打开文本文件,选项为QIODevice::ReadOnly和QIODevice::Text的并集
QIODevice::ReadOnly表示只读
QIODevice::Text表示打开的是文本文件
cpp
//用QFile绑定一个文件
QFile file("example.txt");
//以读的方式打开文件
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "无法打开文件";
return;
}
因为我们的程序运行目录没有example.txt,所以上面的程序会输出无法打开文件
当文件不存在时我们可以以写的方式创建该文件, 上面的代码可以完善为
cpp
//用QFile绑定一个文件
QFile file("example.txt");
//以读的方式打开文件
if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
qDebug() << "无法打开文件";
qDebug() << "开始创建文件";
//以写的方式打开文件
if(!file.open(QIODevice::WriteOnly|QIODevice::Text)){
qDebug() << "创建文件失败";
return;
}
}
向文件写入文本
打开文件后,我们需要用一个QTextStream绑定打开的文件,这样可以实现读写
cpp
//用QTextStream绑定file
QTextStream out(&file);
//向out写就是向文件写
out << "Hello, QFile!" << endl;
out << "This is a test file." << endl;
//写完关闭文件
file.close();
此时我们运行程序,程序输出
cpp
无法打开文件
开始创建文件
在程序的运行目录创建一个example.txt文件

打开example.txt文件可以看到文件内容
cpp
Hello, QFile!
This is a test file.
从文件中读取文本
如果存在文件example.txt,则从文件中读取
QTextStream 有成员函数atEnd用来判断是否读取到文件末尾
cpp
bool QTextStream::atEnd() const
读取文件内容并打印
cpp
//打开成功则读取文本内容
QTextStream in(&file);
//判断文本流是否读取到文件末尾
while(!in.atEnd()){
//每次读取一行
auto line = in.readLine();
qDebug() << line;
}
//读完关闭文件
file.close();
程序会输出
cpp
"Hello, QFile!"
"This is a test file."
练习
以只读方式打开文件example.txt,如果文件不存在则创建这个文件,并向文件中写入两行数据,如果文件存在,则读取这个文件,并按行打印读取内容。
读写方式打开文件
我们可以用读写方式打开一个文件,这样如果文件不存在则自动创建了。
cpp
void file_rw(){
//用QFile绑定一个文件
QFile file("example.txt");
//以读的方式打开文件
if(!file.open(QIODevice::ReadWrite|QIODevice::Text)){
return;
}
file.close();
}
如果文件不存在则创建,并且想以追加的方式打开
cpp
void file_append(){
//用QFile绑定一个文件
QFile file("example.txt");
//以读的方式打开文件
if(!file.open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Text)){
return;
}
file.close();
}
打开二进制文件
打开二进制文件,只需要设置打开的模式即可,因为是二进制文件,所以不要指定QIODevice::Text
下面我们以读写的方式打开
cpp
void write_binary(){
QFile file("binary.dat");
if(!file.open(QIODevice::ReadWrite)){
qDebug() << "无法以只读的方式打开文件";
return;
}
file.close();
}
向文件写入二进制数据
QFile有成员函数write,可直接向文件中写数据
cpp
inline qint64 write(const QByteArray &data);
参数为QByteArray, QByteArray是Qt提供的字节数组,常用于一些二进制数据的存储,比如以后给大家讲网络编程时网络传输的字节流,图片的二进制数据,文件的二进制数据等。
我们可以将要写入的数据放入QByteArray中, 然后调用write函数将QByteArray数据写入文件
cpp
//将二进制文件放入字节数组
QByteArray data;
data.append(0x01);
data.append(0x02);
data.append(0x03);
//向文件写入二进制数据
file.write(data);
//关闭文件描述符
file.close();
执行上述程序会创建文件binary.dat并写入二进制数据
打开文件看到数据

notepad++可以安装插件查看,点击安装

安装后,点击插件View in HEX

此时能看到二进制数据

练习:
向binary.dat中写入一些二进制数据
从文件读取二进制数据
QFile的成员函数readAll能一次性读取文件内容,
QFile继承自QFileDevice, QFileDevice又继承自QIODevice
readAll是QIODevice的成员函数,所以QFile继承QIODevice也包含了readAll函数
cpp
QByteArray QIODevice::readAll()
打开binary.dat并读取其中的二进制数据打印出来
cpp
void read_binary(){
QFile file("binary.dat");
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "无法打开文件进行读取";
return;
}
QByteArray data = file.readAll();
for (char byte : data) {
qDebug() << "字节:" << static_cast<int>(byte);
}
file.close();
}
练习
以二进制方式打开一张图片,然后用二进制的方式保存为另一个图片文件
答案
cpp
void copy_pic(){
QFile file("src.png");
//以读的方式打开源文件
if(!file.open(QIODevice::ReadOnly)){
qDebug() << "无法打开文件进行读取";
return;
}
// 读取二进制数据
QByteArray data = file.readAll();
file.close();
QFile copy_file("copy.png");
// 以写的方式打开二进制文件
if(!copy_file.open(QIODevice::WriteOnly)){
qDebug() << "无法打开文件进行写入";
return;
}
// 写入数据
copy_file.write(data);
// 关闭文件描述符
copy_file.close();
}
判断文件是否存在
QFile有一个静态成员函数exists,用来判断某个文件是否存在
cpp
[static] bool QFile::exists(const QString &fileName)
示例
cpp
if (QFile::exists("example.txt")) {
qDebug() << "文件存在";
} else {
qDebug() << "文件不存在";
}
删除文件
QFile有一个静态成员函数remove, 删除指定文件
cpp
[static] bool QFile::remove(const QString &fileName)
示例
cpp
if (QFile::remove("example.txt")) {
qDebug() << "文件已删除";
} else {
qDebug() << "无法删除文件";
}
重命名文件
QFile有一个静态成员函数rename,删除指定文件
cpp
[static] bool QFile::rename(const QString &oldName, const QString &newName)
示例
cpp
if (QFile::rename("example.txt", "new_example.txt")) {
qDebug() << "文件已重命名";
} else {
qDebug() << "无法重命名文件";
}
获取文件信息
QFileInfo是获取文件信息的类,通过QFile构造一个QFileInfo变量即可, 使用时需包含
cpp
QFileInfo::QFileInfo(const QFile &file)
示例
cpp
void file_info(){
QFile file("example.txt");
QFileInfo file_info(file);
qDebug() << "文件名称:" << file_info.fileName();
qDebug() << "文件大小:" << file_info.size() << "字节";
qDebug() << "文件路径:" << file_info.absoluteFilePath();
}