文章目录
一、QFile类介绍
QFile 类提供了一个用于从文件读取和写入文件的接口。QFile
是 Qt 中用于文件 I/O 的类,支持读取和写入文本和二进制文件。可以单独使用,也可以与 QTextStream
或 QDataStream
结合使用。
QFile类使用要点:
-
文件名:
文件名通常在构造函数中指定,也可以通过
setFileName()
方法设置 -
文件分隔符:
QFile
期望使用 ‘/’ 作为文件分隔符,不支持其他分隔符(例如 ‘\’)。 -
文件操作:
- 使用
exists()
检查文件是否存在,使用remove()
删除文件。 - 使用
open()
打开文件,close()
关闭文件,flush()
刷新文件。 - 读取和写入数据通常通过
QDataStream
或QTextStream
,也可以使用继承自QIODevice
的read()
,readLine()
,readAll()
,write()
方法。
- 使用
-
文件位置和大小
- 使用
size()
获取文件大小,pos()
获取当前文件位置,seek()
移动到新文件位置。 - 使用
atEnd()
检查是否到达文件末尾。
- 使用
-
文件名编码转换
-
使用 QFile, QFileInfo 和 QDir 访问文件系统时,可以使用 Unicode 文件名
-
使用 encodeName() 和 decodeName() 函数在 Unicode 文件名和 8 位编码文件名之间进行转换。
-
-
QFile
不会发出aboutToClose()
,bytesWritten()
,readyRead()
等信号,因此不适合用于读取和写入某些类型的文件,如 Unix 平台上的设备文件。 -
文件权限在 Unix 类型系统和 Windows 上的处理方式不同。
逐行读取文本文件:
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
QByteArray line = file.readLine();
process_line(line);
}
- 默认情况下,QFile 假设二进制,即不对文件中存储的字节进行任何转换。
QIODevice::Text
标志告诉 Qt 将 Windows 风格的行终止符 (“\r\n”) 转换为 C++ 风格的终止符 (“\n”)。
使用QTextStream 流逐行读取文本文件:
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
process_line(line);
}
QTextStream
负责将存储在磁盘上的 8 位数据转换为 16 位 Unicode QString
使用QTextStream 流写入文件:
QFile file("out.txt");
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
out << "The magic number is: " << 49 << "\n";
- 使用
QTextStream
写入文本时,可以使用<<
操作符,可接受各种数据类型(包括QString) QDataStream
与QTextStream
类似,使用 operator<<() 写入数据并使用 operator>>() 读取
二、Public Types(公共成员类型)
-
QFile::DecoderFn
-
类型说明:
QFile::DecoderFn
定义了一个函数指针,指向一个接受QByteArray
类型参数并返回QString
类型的函数,这个函数用于解码文件名,如:QString myDecoderFunc(const QByteArray &localFileName);
可以使用
setDecodingFunction()
函数来设置一个解码函数,用于处理文件名的解码任务。 -
示例:
QString myDecoderFunc(const QByteArray &localFileName) { // 这里可以添加解码逻辑 return QString::fromLocal8Bit(localFileName); // } QFile file; file.setDecodingFunction(myDecoderFunc);
-
三、Public Functions(公共成员函数)
1.构造对象
QFile::QFile(const QString &name, QObject *parent)
QFile::QFile(QObject *parent)
QFile::QFile(const QString &name)
QFile::QFile()
- 函数说明:
- 带文件名和父对象的构造函数: 允许在创建文件对象时指定文件名和父对象。这使得文件对象可以被自动管理(例如,当父对象被销毁时,文件对象也会被销毁)。
- 带父对象的构造函数: 只指定父对象,文件名可以在之后通过
setFileName()
方法设置。 - 带文件名的构造函数: 只指定文件名,文件对象没有父对象。
- 无参数的默认构造函数: 创建一个没有文件名和父对象的文件对象,文件名可以在之后通过
setFileName()
方法设置。
- 注意事项:
- 文件名可以在构造函数中指定,也可以在构造后通过
setFileName()
方法设置。 - 文件操作通常需要检查操作是否成功(例如,使用
open()
方法返回的布尔值)。
- 文件名可以在构造函数中指定,也可以在构造后通过
2.open函数–打开文件
bool QFile::open(FILE *fh, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)
-
函数说明:
打开一个现有的文件句柄,并根据指定的模式和标志进行操作。成功返回
true
,失败返回false
。 -
参数说明:
-
FILE *fh
:现有的文件句柄。 -
QIODevice::OpenMode mode
:打开文件的模式。一般是OpenMode Flag 值的 OR 组合
这个枚举类型与 open() 一起使用,以描述设备打开的模式。它也由openMode()
返回。常量 值 描述 QIODevice::NotOpen 0x0000 设备未打开。 QIODevice::ReadOnly 0x0001 设备以只读模式打开。 QIODevice::WriteOnly 0x0002 设备以只写模式打开。注意,对于文件系统子类(例如 QFile),这种模式意味着截断,除非与 ReadOnly、Append 或 NewOnly 组合使用。 QIODevice::ReadWrite ReadOnly | WriteOnly ReadOnly | WriteOnly QIODevice::Append 0x0004 设备以追加模式打开,所有数据都写入文件末尾。 QIODevice::Truncate 0x0008 如果可能,设备在打开前会被截断。设备的早期内容将丢失。 QIODevice::Text 0x0010 读取时,行结束符被转换为 ‘\n’。写入时,行结束符被转换为本地编码,例如 Win32 中的 ‘\r\n’。 QIODevice::Unbuffered 0x0020 绕过设备中的任何缓冲区。 QIODevice::NewOnly 0x0040 如果要打开的文件已存在,则失败。仅在文件不存在时创建并打开文件。操作系统保证你是唯一一个创建和打开文件的。注意,这种模式意味着只写,并且允许与 ReadWrite 组合使用。这个标志目前只影响 QFile。将来其他类可能会使用这个标志,但在此之前,使用这个标志与任何非 QFile 的类可能会导致未定义的行为。(自 Qt 5.11 起) QIODevice::ExistingOnly 0x0080 如果要打开的文件不存在,则失败。这个标志必须与 ReadOnly、WriteOnly 或 ReadWrite 一起指定。注意,单独使用这个标志与 ReadOnly 是多余的,因为 ReadOnly 在文件不存在时已经会失败。这个标志目前只影响 QFile。将来其他类可能会使用这个标志,但在此之前,使用这个标志与任何非 QFile 的类可能会导致未定义的行为。(自 Qt 5.11 起) -
QFileDevice::FileHandleFlags handleFlags
:文件句柄标志,默认为DontCloseHandle
。- 如果在
handleFlags
中指定了AutoCloseHandle
,则调用close()
会关闭文件描述符。 - 如果没有指定
AutoCloseHandle
,则close()
只会刷新文件,不会关闭文件描述符。
- 如果在
-
-
示例:
#include <stdio.h> void printError(const char* msg) { QFile file; file.open(stderr, QIODevice::WriteOnly); file.write(msg, qstrlen(msg)); // write to stderr file.close(); }
bool QFile::open(int fd, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)
-
函数说明:
用于以特定的模式打开一个文件描述符,这个重载函数允许直接使用文件描述符而不是文件名来打开文件。成功打开文件时返回
true
,否则返回false
。 -
参数说明:
fd
(类型为int
):要打开的文件描述符。mode
(类型为QIODevice::OpenMode
):文件打开的模式,如只读、只写、读写等。handleFlags
:用于指定额外选项的标志。- 如果在
handleFlags
中指定了AutoCloseHandle
,则调用close()
会关闭文件描述符。 - 如果没有指定
AutoCloseHandle
,则close()
只会刷新文件,不会关闭文件描述符。
- 如果在
-
示例:
int fd = open("example.txt", O_RDONLY); // 创建 QFile 对象并打开文件描述符 QFile file; if (file.open(fd, QIODevice::ReadOnly)) { // 读取文件内容 QByteArray content = file.readAll(); qDebug() << "File content:" << content; // 关闭文件 file.close(); } else { qDebug() << "Failed to open file"; } // 关闭文件描述符 close(fd);
-
注意事项:
- 如果文件描述符不是指向常规文件(例如标准输入-0、标准输出-1或标准错误-2),则可能无法进行
seek()
操作。
- 如果文件描述符不是指向常规文件(例如标准输入-0、标准输出-1或标准错误-2),则可能无法进行
3.fileName/setFileName函数–获取/设置当前 QFile对象关联的文件名
[override virtual] QString QFile::fileName() const
void QFile::setFileName(const QString &name)
-
函数说明:
用于设置文件的名称。这个名称可以是文件名、相对路径或绝对路径。
-
示例:
QFile file; QDir::setCurrent("/tmp"); file.setFileName("readme.txt"); QDir::setCurrent("/home"); file.open(QIODevice::ReadOnly); // opens "/home/readme.txt" under Unix
-
注意事项:
- 如果文件已经被打开,不应调用此函数。这是因为一旦文件被打开,其路径和名称通常就固定了,改变文件名可能会导致不一致的状态。
- 如果文件名没有包含路径或只包含相对路径,那么在调用
open()
函数时,将使用应用程序的当前工作目录作为文件的路径。
4.exist函数–检查文件是否存在
[static] bool QFile::exists(const QString &fileName)
bool QFile::exists() const
-
函数说明:
-
第一个函数:
它接受一个文件名(可以是绝对路径或相对路径)作为参数,并检查这个文件是否存在。
- 如果文件存在,返回
true
;如果文件不存在或出现错误(如权限问题),返回false
。 - 特别地,如果提供的文件名是一个符号链接,并且该符号链接指向的文件不存在,则该函数也会返回
false
。
- 如果文件存在,返回
-
第二个函数:
它检查通过
fileName()
获取的当前文件名对应的文件是否存在。如果该文件存在,返回true
;否则返回false
。
-
-
示例:
// 检查文件是否存在 QString fileName = "example.txt"; if (QFile::exists(fileName)) { qDebug() << "File exists."; } else { qDebug() << "File does not exist."; } // 创建 QFile 对象并检查关联文件是否存在 QFile file; file.setFileName(fileName); if (file.exists()) { qDebug() << "File associated with QFile object exists."; } else { qDebug() << "File associated with QFile object does not exist."; }
5.copy函数–复制源文件到目标文件
bool QFile::copy(const QString &newName)
[static] bool QFile::copy(const QString &fileName, const QString &newName)
-
函数说明:
用于将当前
QFile
对象关联的文件(通过fileName()
获取)复制到一个新文件。如果复制成功,返回true
;如果失败(例如目标文件已存在),返回false
。复制前会关闭源文件,确保数据的一致性。 -
参数说明:
- fileName:源文件名
- newName:目标文件名
-
示例:
QFile file("source.txt"); QString newName = "destination.txt"; // 使用成员函数复制文件 if (file.copy(newName)) { qDebug() << "File copied successfully."; } else { qDebug() << "File copy failed."; } // 使用静态函数复制文件 if (QFile::copy("source.txt", "destination2.txt")) { qDebug() << "File copied successfully using static function."; } else { qDebug() << "File copy failed using static function."; }
-
注意事项:
如果目标文件存在则不会覆盖
6.link函数–创建关联文件链接
bool QFile::link(const QString &linkName)
[static] bool QFile::link(const QString &fileName, const QString &linkName)
-
函数说明:
用于创建一个指向当前
QFile
对象关联文件(通过fileName()
获取)的链接。链接的类型取决于操作系统的文件系统,例如在 Windows 上是快捷方式,在 Unix 上是符号链接。如果创建链接成功,返回true
;如果失败(例如目标链接已存在),返回false
。 -
参数说明:
- fileName:文件名称
- linkName:链接名称
-
示例:
QFile file("source.txt"); QString linkName = "source_link.txt"; // 使用成员函数创建链接 if (file.link(linkName)) { qDebug() << "Link created successfully."; } else { qDebug() << "Failed to create link:" << file.errorString(); } // 使用静态函数创建链接 if (QFile::link("source.txt", "source_link2.txt")) { qDebug() << "Link created successfully using static function."; } else { qDebug() << "Failed to create link using static function:" << QFile::errorString(); }
-
注意事项:
如果链接存在,则会创建失败
7.rename函数–重命名文件
bool QFile::rename(const QString &newName)
[static] bool QFile::rename(const QString &oldName, const QString &newName)
-
函数说明:
用于将当前
QFile
对象关联的文件(通过fileName()
获取)重命名为newName
。如果重命名成功,返回true
;如果失败(例如目标文件名已存在),返回false
。重命名操作会关闭文件,确保文件状态的一致性。 -
参数说明:
- oldName:原始文件名
- newName:新文件名
-
示例:
QFile file("source.txt"); QString newName = "destination.txt"; // 使用成员函数重命名文件 if (file.rename(newName)) { qDebug() << "File renamed successfully."; } else { qDebug() << "Failed to rename file:" << file.errorString(); } // 使用静态函数重命名文件 if (QFile::rename("source.txt", "destination2.txt")) { qDebug() << "File renamed successfully using static function."; } else { qDebug() << "Failed to rename file using static function:" << QFile::errorString(); }
8.moveToTrash函数–移动文件到垃圾箱
bool QFile::moveToTrash()
[static] bool QFile::moveToTrash(const QString &fileName, QString *pathInTrash = nullptr)
-
函数说明:
用于将当前
QFile
对象关联的文件(通过fileName()
获取)移动到垃圾箱。如果移动成功,返回true
,并更新fileName()
为文件在垃圾箱中的路径。如果移动失败,返回false
。 -
参数说明:
- fileName:文件名
- pathInTrash:文件在垃圾箱中的路径
-
示例:
QFile file("example.txt"); // 使用成员函数移动文件到垃圾箱 if (file.moveToTrash()) { qDebug() << "File moved to trash successfully. New path:" << file.fileName(); } else { qDebug() << "Failed to move file to trash."; } // 使用静态函数移动文件到垃圾箱 if (QFile::moveToTrash("example.txt", &pathInTrash)) { qDebug() << "File moved to trash successfully. Path in trash:" << pathInTrash; } else { qDebug() << "Failed to move file to trash."; }
9.remove函数–删除文件
bool QFile::remove()
[static] bool QFile::remove(const QString &fileName)
-
函数说明:
删除由
fileName()
指定的文件。如果成功返回true
;否则返回false
。在删除文件之前会关闭该文件。 -
参数说明:
- fileName:指定要删除的文件名
-
示例:
// 创建一个 QFile 对象并设置文件名 QFile file("example.txt"); // 检查文件是否存在 if (file.exists()) { // 调用 remove() 成员函数删除文件 bool success = file.remove(); if (success) { qDebug() << "File removed successfully."; } else { qDebug() << "Failed to remove the file."; } } else { qDebug() << "File does not exist."; } // 使用静态 remove() 函数删除文件 success = QFile::remove("example.txt"); if (success) { qDebug() << "File removed successfully using static function."; } else { qDebug() << "Failed to remove the file using static function."; }
10.symLinkTarget函数–符号链接所指向文件或目录的绝对路径
QString QFile::symLinkTarget() const
[static] QString QFile::symLinkTarget(const QString &fileName)
-
函数说明:
返回由
fileName
指定的符号链接所指向的文件或目录的绝对路径,如果fileName
不对应于一个符号链接,则返回一个空字符串。 -
参数说明:
- fileName:符号链接名称
-
示例:
// 定义符号链接的文件名 QString linkName = "link.txt"; // 使用静态函数获取符号链接的目标路径 QString targetPath = QFile::symLinkTarget(linkName); if (targetPath.isEmpty()) { qDebug() << "The file is not a symbolic link or does not exist."; } else { qDebug() << "Symbolic link points to:" << targetPath; } // 检查符号链接指向的文件是否存在 if (QFile::exists(targetPath)) { qDebug() << "The file pointed by the symbolic link exists."; } else { qDebug() << "The file pointed by the symbolic link does not exist."; }
四、Reimplemented Public Functions(重新实现的公共函数)
1.fileName函数–获取文件名称
[override virtual] QString QFile::fileName() const
-
函数说明:
这个函数重写自
QFileDevice::fileName()
返回通过
setFileName()
设置的名称,或者返回给QFile
构造函数的名称。
2.open函数–打开文件
[override virtual] bool QFile::open(QIODevice::OpenMode mode)
-
函数说明:
这个函数重写自
QIODevice::open(QIODevice::OpenMode mode)
。使用指定模式打开文件,如果成功返回
true
;否则返回false
。如果在只写或读写模式下打开文件,并且文件不存在,函数将尝试首先创建文件,然后再打开它。 -
示例:
// 创建 QFile 对象并设置文件名 QFile file("example.txt"); // 指定打开模式为读写模式 QIODevice::OpenMode mode = QIODevice::ReadWrite; // 尝试打开文件 if (file.open(mode)) { qDebug() << "File opened successfully."; // 进行文件读写操作... // 关闭文件 file.close(); } else { qDebug() << "Failed to open the file."; }
3.permissions函数–获取文件权限
[override virtual] QFileDevice::Permissions QFile::permissions() const
-
函数说明:
这个函数重写自
QFileDevice::permissions
。用于获取文件权限
4.setPermissions函数–修改文件权限
[override virtual] bool QFile::setPermissions(QFileDevice::Permissions permissions)
-
函数说明:
这个函数重写自
QFileDevice::setPermissions(QFileDevice::Permissions permissions)
。将文件的权限设置为指定的权限。如果成功返回
true
,如果权限无法修改则返回false
。 -
示例:
// 设置文件为只读权限 QFileDevice::Permissions permissions = QFileDevice::ReadUser; bool result = file.setPermissions(permissions); if (result) { qDebug() << "Permissions set successfully"; } else { qDebug() << "Failed to set permissions"; }
4.resize函数–调整文件的大小
[override virtual] bool QFile::resize(qint64 sz)
-
函数说明:
这个函数重写自
QFileDevice::resize(qint64 sz)
。成功调整文件大小时返回true
,否则返回false
。 -
参数说明:
sz
(类型为qint64
):新的大小,单位是字节。如果这个值小于当前文件的大小,文件将被截断;如果大于当前大小,文件将被扩展,新扩展的部分通常填充为零。
5.size函数–获取文件大小
[override virtual] qint64 QFile::size() const
-
函数说明:
这个函数重写自:
QFileDevice::size() const
。 返回文件的大小,以字节为单位。 -
示例:
QFile file("example.txt"); // 打开文件以获取文件大小 if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Failed to open file"; return 1; } qint64 size = file.size(); file.close(); // 输出文件大小 qDebug() << "File size:" << size << "bytes";
-
注意事项:
- 如果文件成功打开,
size()
返回文件的字节数。 - 如果文件未打开或遇到错误,返回值是未定义的。
- 如果文件成功打开,
五、Static Public Members(静态公共函数)
1.decodeName函数–文件名解码
[static] QString QFile::decodeName(const QByteArray &localFileName)
[static] QString QFile::decodeName(const char *localFileName)
- 函数说明:
- 第一个函数用于将本地编码的文件名(
QByteArray
类型)解码为Unicode字符串(QString
类型)。 - 第二个函数是
decodeName
的重载版本,接受一个const char *
类型的本地文件名。
- 第一个函数用于将本地编码的文件名(
2.encodeName函数–文件名编码
[static] QByteArray QFile::encodeName(const QString &fileName)
-
函数说明:
这个函数用于将Unicode字符串(
QString
类型)编码为本地8位编码(QByteArray
类型)。