QFile 概述
QFile
是Qt框架中用于文件操作的类(位于QtCore
模块),继承自 QIODevice
,提供文件的读写、状态查询和路径管理功能。它与 QTextStream
、QDataStream
配合使用,可简化文本和二进制数据的处理,并具备跨平台兼容性。
文件操作类 QFile
主要功能:
- 文件读写: QFile 支持打开文件进行读取或写入操作
- 文件信息:可以检索有关文件的信息,如大小、修改日期等。
- 文件操作:提供了对文件进行重命名、移动、删除等操作的能力。
- 错误处理: QFile 在操作文件时提供了错误处理机制,可以通过相应的函数检查和获取错误息。
常用方法:
- open() :打开一个文件。需要指定模式(如只读、只写、读写等)。
- close() :关闭文件。
- read() 和 write() :用于读取和写入数据。
- exists() :检查文件是否存在。
- remove() :删除文件。
- copy() :复制文件。
QFile读取文件数据
创建一个按钮 “读取文件” 当按钮被点击时,会打开指定路径的文件 test.txt ,将该文件的内容读取出来并打印。
创建一个按钮,并转为槽,信号选择clicked。
以上两个函数(QFile、QFile(const QString &name))二选一
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_btnRead_clicked()
{
// 1.打开文件
// 方式一:
// QFile myFile("D:/C++Pro/test.txt"); 创建QFile对象并设置文件路径为绝对路径D:/C++Pro/test.txt
// 方式二:
// 创建QFile对象并设置文件路径为绝对路径D:/C++Pro/test.txt
QFile myFile;
myFile.setFileName("D:/C++Pro/test.txt");
// 判断 open 返回值,返回 true 文件成功打开,返回 false 打开失败,后续的操作(如:read,write)均无效
if( !myFile.open(QIODevice::ReadOnly | QIODevice::Text) ) // open 以只读和文本模式打开。
{
qDebug() << "文件打开失败";
}
// 2.读取数据
char cData[100] = {'\0'};
// 如果返回-1,表示读取发生错误,直接return程序结束
if( myFile.read(cData, 100) == -1 )
return;
// 3.输出数据
qDebug() << cData;
// 4.关闭
myFile.close();
}
open 在 QIODevice 里面,所以需要进入 QIODevice 里面查找 open 的访问权限。
QFile 继承于 QFileDevice,QFileDevice 继承于 QIODevice。在 QIODevice 里面找到 Member Type Documentation,如下图:
QFile创建并写入文件
同样,创建一个按钮 “写入文件” 当按钮被点击时,会在指定的路径创建文件 test2.txt ,将该数据写入文件中。
创建一个按钮,并转为槽,信号选择clicked。
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_btnWrite_clicked()
{
// 1.打开文件
QFile file("D:/C++Pro/test2.txt"); // 创建QFile对象并设置文件路径为绝对路径
if( !file.open(QIODevice::WriteOnly | QIODevice::Text)) // open 以只写模式和文本模式打开文件。
// QIODevice::WriteOnly:文件不存在则创建,存在则覆盖。
// QIODevice::Text:自动处理换行符(如Windows中将\n转换为\r\n)。
{
qDebug() << "文件创建失败";
}
// 2.写入数据
// 将字符串写入文件,若写入失败(返回-1)则直接返回。
if( file.write("This is the first file I created using QT") == -1 )
{
return;
}
// 3.关闭文件
file.close();
}
QTextStream
QTextStream 的主要特性成一个表格:
QTextStream 是一个功能强大的类,用于处理文本数据,特别是在需要考虑字符编码和文本格式化的情况下。通过这些特性,它提供了一种灵活而强大的方式来读写和操作文本。
编程示例:
以下是一个更详细的示例,展示了如何使用 QTextStream 来读写文件:
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_stramWrite_clicked()
{
QFile file("D:/C++Pro/test2.txt");
if( !file.open(QIODevice::WriteOnly | QIODevice::Text) )
{
qDebug() << "error file";
return;
}
QTextStream out(&file);
// 设置字符编码格式为:UTF-8
out.setCodec("UTF-8");
// 向文件写入数据
out << "hello QT";
// 关闭文件
file.close();
}
void Widget::on_streamRead_clicked()
{
QFile file("D:/C++Pro/test.txt"); // QFile 对象(file)与文件名的路径关联
if( !file.open(QIODevice::ReadOnly | QIODevice::Text) ) // 显式调用 open() 打开文件
{
qDebug() << "error file";
}
QTextStream in(&file); // 将已打开的 QFile 对象传给 QTextStream,使其能操作文件内容。
// 设置字符编码格式
in.setCodec("UTF-8");
// 读取文件中每行的数据
while ( !in.atEnd() ) {
QString str = in.readLine();
qDebug() << str;
}
// 关闭文件
file.close();
}
setCodec
、atEnd
和 readLine
三个 API 的详细解释
setCodec
函数原型:setCodec(const char *codecName)
作用
设置文本流的字符编码格式,用于读写文本时的编码/解码。例如,将文本编码设为 UTF-8
、GBK
或 ISO-8859-1
。
参数
-
codecName
:字符串形式的编码名称(如"UTF-8"
、"GBK"
)。
使用场景
-
当需要确保文本文件以特定编码(如 UTF-8)保存时。
-
解决跨平台或跨语言环境下的乱码问题。
编程示例
QFile file("data.txt");
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out.setCodec("UTF-8"); // Qt5 及之前版本
out << "你好,Qt!"; // 写入 UTF-8 编码的中文
注意事项
-
Qt 版本差异:
-
Qt5 及之前:使用
setCodec("UTF-8")
。 -
Qt6:
setCodec
被弃用,改用setEncoding(QStringConverter::Utf8)
。
-
-
BOM 问题:
-
Windows 记事本依赖 BOM(字节顺序标记)识别 UTF-8 文件。若需兼容,需启用 BOM:
out.setGenerateByteOrderMark(true); // 添加 BOM
-
-
读写一致性:读取文件时需使用相同的编码,否则会乱码。
atEnd
函数原型:bool atEnd() const
作用
检查当前流是否已读取到末尾(没有更多数据可读)。
返回值
-
true
:流已到末尾,无数据可读。 -
false
:流中仍有数据。
使用场景
-
在循环中逐行读取文件时,作为循环终止条件。
-
避免在无数据时继续读取导致错误。
编程示例
QFile file("data.txt");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
in.setCodec("UTF-8"); // 设置编码与写入时一致
while (!in.atEnd()) { // 循环直到文件末尾
QString line = in.readLine();
qDebug() << line;
}
注意事项
-
并非实时更新:
atEnd()
的状态在每次读取操作后更新。 -
二进制文件:对二进制流(如
QDataStream
)可能不适用。 -
性能:频繁调用
atEnd()
无性能问题,因内部缓冲机制高效。
readLine
函数原型:QString readLine(qint64 maxlen = 0)
作用
从流中读取一行文本,直到遇到换行符(\n
或 \r\n
)或文件末尾。
参数
-
maxlen
(可选):最大读取长度。若设为0
(默认),读取整行。
返回值
-
QString
:读取的一行文本(不包含换行符)。 -
若流已到末尾,返回空字符串。
使用场景
-
逐行读取文本文件(如日志、CSV、配置文件)。
-
处理用户输入的逐行命令。
编程示例
QFile file("data.txt");
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
in.setCodec("UTF-8");
QString line;
while (!(line = in.readLine()).isNull()) { // 逐行读取
processLine(line); // 处理每行数据
}
注意事项
-
换行符处理:
-
自动忽略换行符(
\n
或\r\n
)。 -
返回的字符串中不包含换行符。
-
-
空行:若某行仅包含换行符,返回空字符串。
-
性能:适合大文件处理,因逐行读取减少内存占用。
-
编码一致性:需确保读取编码与文件实际编码一致。