Qt开发:QFileInfo详解

一、QFileInfo 简介

QFileInfo 提供了一个对象化的方式,用于访问文件系统中单个文件的信息。它可以接受:

  • 文件名字符串(绝对路径或相对路径)
  • QDir + QString 组合
  • QFile 对象等

二、常用的构造函数

2.1 QFileInfo::QFileInfo(const QFileInfo &fileinfo)
拷贝构造函数遵循 Qt 的值语义设计 —— 就像 QString 一样,可以安全地拷贝、赋值,而不会带来资源管理的麻烦。

使用场景
复制一个已有的 QFileInfo 以传递或临时修改:

QFileInfo original("C:/data/report.txt");
QFileInfo copy(original);

// 两者指向同一个文件,但是不同的对象
qDebug() << copy.fileName();  // 输出: "report.txt"

在函数中作为参数传递(值传递或引用传递):

void printFileInfo(QFileInfo fi) {
    qDebug() << "Path:" << fi.absoluteFilePath();
}

或者更推荐(避免不必要的拷贝):

void printFileInfo(const QFileInfo &fi) {
    qDebug() << "Path:" << fi.absoluteFilePath();
}

在容器中存储多个文件信息:

QList<QFileInfo> fileList;
fileList << QFileInfo("a.txt") << QFileInfo("b.txt");

for (const QFileInfo &fi : fileList) {
    qDebug() << fi.fileName();
}

2.2 QFileInfo::QFileInfo(const QDir &dir, const QString &file)

参数说明

  • dir:一个 QDir 对象,表示某个目录;
  • file:目录下的文件名或相对路径。

这个构造函数会自动组合 dir.absolutePath() 和 file,构造出一个完整路径下的 QFileInfo 对象。

使用场景
在目录中访问文件:

QDir dir("C:/MyFolder");
QFileInfo info(dir, "data.txt");

qDebug() << "绝对路径:" << info.absoluteFilePath();
qDebug() << "是否存在:" << info.exists();

遍历文件夹时更灵活:

QDir dir("C:/Logs");
QStringList fileNames = dir.entryList(QDir::Files);

for (const QString &name : fileNames) {
    QFileInfo info(dir, name);
    qDebug() << "文件:" << info.fileName()
             << "大小:" << info.size()
             << "最后修改:" << info.lastModified().toString();
}

这个方式比 QFileInfo(“C:/Logs/” + name) 更可靠,因为它会自动处理路径分隔符和相对路径问题。

判断某个目录中的某个相对路径是否存在:

QDir dir("D:/Projects");
QFileInfo info(dir, "subdir/readme.md");

if (info.exists()) {
    qDebug() << "文件存在,完整路径是:" << info.absoluteFilePath();
}

2.3 QFileInfo::QFileInfo(const QFile &file)

参数说明

  • file:一个已经构造好的 QFile 对象(不需要已打开,但需要设置了文件路径)。

使用场景
这个构造方式适合以下情况:

  • 已经创建了一个 QFile 对象(可能还要进行读写),并想获取它的元信息。
  • 在同一个地方复用 QFile + QFileInfo,代码更整洁。

示例代码:

QFile file("C:/data/report.txt");
QFileInfo fileInfo(file);

qDebug() << "文件名:" << fileInfo.fileName();
qDebug() << "完整路径:" << fileInfo.absoluteFilePath();
qDebug() << "文件大小:" << fileInfo.size();
qDebug() << "最后修改时间:" << fileInfo.lastModified().toString();

使用 QFile 打开文件并用 QFileInfo 获取属性

QFile file("example.txt");

if (file.open(QIODevice::ReadOnly)) {
    QByteArray content = file.readAll();
    file.close();

    QFileInfo info(file);
    qDebug() << "文件大小:" << info.size();
    qDebug() << "文件扩展名:" << info.suffix();
}

2.4 QFileInfo::QFileInfo(const QString &file)

参数说明

  • file:文件路径字符串,可以是:绝对路径,例如 “C:/data/file.txt”;相对路径,例如 “docs/readme.md”。

作用:通过传入一个文件路径,创建一个 QFileInfo 对象,从而访问该文件的各种信息:是否存在、名称、大小、扩展名、路径、时间戳等。

示例代码:

QFileInfo info("C:/Projects/example.txt");

if (info.exists()) {
    qDebug() << "文件名:" << info.fileName();               // "example.txt"
    qDebug() << "绝对路径:" << info.absoluteFilePath();     // "C:/Projects/example.txt"
    qDebug() << "大小:" << info.size() << "字节";           // 如:1024
    qDebug() << "扩展名:" << info.suffix();                 // "txt"
    qDebug() << "创建时间:" << info.created().toString();   // 2025-04-14 12:30:00
} else {
    qDebug() << "文件不存在";
}

2.5 QFileInfo::QFileInfo()
功能说明:这是 QFileInfo 的默认构造函数,构造一个 无效的、空的 QFileInfo 对象。

常见用法
延迟设置文件路径(动态赋值):

QFileInfo info;  // 空构造
info.setFile("C:/test/data.txt");

if (info.exists()) {
    qDebug() << "文件大小:" << info.size();
}

在循环或类中使用再赋值:

QStringList files = {"a.txt", "b.txt", "c.txt"};
QFileInfo info;

for (const QString &file : files) {
    info.setFile(file);
    qDebug() << file << "大小:" << info.size();
}

什么时候用默认构造?
在这里插入图片描述

三、常用函数的介绍和使用

3.1 QDir absoluteDir() const

功能说明
QFileInfo::absoluteDir() 返回一个 QDir 对象,它表示当前文件的上级目录(以绝对路径表示)。这个函数常用于:拿到一个文件路径后,想获取它所在的目录,然后可能在该目录下继续操作其他文件。

示例代码:

QFileInfo info("C:/Projects/MyApp/config/settings.ini");

QDir parentDir = info.absoluteDir();

qDebug() << "文件绝对路径:" << info.absoluteFilePath();   // C:/Projects/MyApp/config/settings.ini
qDebug() << "所在目录路径:" << parentDir.absolutePath();  // C:/Projects/MyApp/config

场景举例
从文件路径中获取文件所在目录:

QString path = QFileDialog::getOpenFileName();
QFileInfo info(path);
QDir dir = info.absoluteDir();

qDebug() << "你选择的文件目录是:" << dir.absolutePath();

遍历与该文件同目录下的其他文件:

QFileInfo info("D:/data/report.csv");
QDir dir = info.absoluteDir();

QStringList files = dir.entryList(QDir::Files);
for (const QString &name : files) {
    qDebug() << "同目录下的文件:" << name;
}

3.2 QString absoluteFilePath() const

功能说明
absoluteFilePath() 返回当前文件的绝对路径,它会根据系统环境返回完整的文件路径。

  • 如果文件路径已经是绝对路径,absoluteFilePath() 会直接返回它。
  • 如果文件路径是相对路径,absoluteFilePath() 会根据当前工作目录(QDir::currentPath())将其转换为绝对路径。

示例代码:
获取绝对文件路径

QFileInfo fileInfo("docs/readme.md");

qDebug() << "文件的绝对路径是:" << fileInfo.absoluteFilePath();

获取已经是绝对路径的文件

QFileInfo fileInfo("/home/user/documents/report.txt");

qDebug() << "文件的绝对路径是:" << fileInfo.absoluteFilePath();

使用场景
获取文件的完整路径并用于进一步操作,比如想在程序中访问文件,获取它的绝对路径:

QFileInfo fileInfo("config/settings.ini");
if (fileInfo.exists()) {
    QString absolutePath = fileInfo.absoluteFilePath();
    // 可以进一步操作文件
    qDebug() << "文件的绝对路径:" << absolutePath;
}

获取相对路径的文件的绝对路径,假设收到一个相对路径,你需要将其转换为绝对路径来执行某些操作:

QFileInfo fileInfo("assets/images/logo.png");
QString absolutePath = fileInfo.absoluteFilePath();
qDebug() << "文件的绝对路径:" << absolutePath;

如果当前工作目录是 “C:/Projects”, 上面代码将返回:

文件的绝对路径: "C:/Projects/assets/images/logo.png"

3.3 QString absolutePath() const

功能说明
QFileInfo::absolutePath() 返回文件所在目录的绝对路径(不包含文件名)。
比如:文件路径是:C:/Projects/MyApp/data/config.ini;absolutePath() 返回:C:/Projects/MyApp/data

示例代码:

#include <QFileInfo>
#include <QDebug>

int main()
{
    QFileInfo info("C:/Projects/MyApp/data/config.ini");

    QString path = info.absolutePath();

    qDebug() << "文件所在目录的绝对路径是:" << path;
    return 0;
}

输出:

文件所在目录的绝对路径是: "C:/Projects/MyApp/data"

相对路径时也能正确处理:

QFileInfo info("logs/output.log");
qDebug() << info.absolutePath();

假如当前工作目录是 D:/App/bin,结果为:

"D:/App/bin/logs"

搭配 QFile、QDir 使用的常见组合:

QFileInfo info("reports/2024_summary.txt");
QString dirPath = info.absolutePath();
QDir dir(dirPath);

QStringList fileList = dir.entryList(QDir::Files);
for (const QString &file : fileList) {
    qDebug() << "同目录文件:" << file;
}

3.4 QString baseName() const

功能说明
baseName() 返回文件名中去掉路径和后缀(扩展名)之后的部分,也就是基础名称。

比如,文件路径是:

/home/user/project/report2024.pdf

那么:

QFileInfo info("/home/user/project/report2024.pdf");
qDebug() << info.baseName();  // 输出: "report2024"

示例代码:

#include <QFileInfo>
#include <QDebug>

int main()
{
    QFileInfo info("C:/Data/backup_2024.tar.gz");
    qDebug() << "baseName:" << info.baseName();
}

输出:

baseName: "backup_2024"

进阶用法
生成同名日志文件:

QFileInfo info("logs/mylog.txt");
QString logName = info.baseName() + "_backup.log";
qDebug() << logName;  // 输出: "mylog_backup.log"

与 UI/文件管理配合:

QString title = QString("正在查看: %1").arg(fileInfo.baseName());
setWindowTitle(title);

3.5 bool caching() const

功能说明
QFileInfo::caching() 用于判断当前 QFileInfo 实例是否开启了内部缓存机制。默认情况下,QFileInfo 会缓存文件的信息(如大小、修改时间等),避免频繁访问磁盘,提高性能。如果你想实时获取最新的文件信息,需要手动刷新,或者关闭缓存。

示例说明:

QFileInfo info("example.txt");
qDebug() << "是否启用缓存:" << info.caching();  // 通常输出 true

相关操作
关闭缓存(实时访问文件系统):

info.setCaching(false);  // 设置为关闭缓存
info.refresh();          // 手动刷新文件信息

当设置 setCaching(false) 后,每次访问文件信息(如 size()、lastModified())时,Qt 都会重新读取实际文件状态。
适用于:文件在运行期间可能被其他程序修改,以及希望读取文件的最新状态。

示例对比:缓存 vs 实时

QFileInfo info("log.txt");
info.setCaching(false); // 禁用缓存

qint64 size1 = info.size();  // 第一次读取
// ...此处 log.txt 文件被外部程序修改...
qint64 size2 = info.size();  // 立即读取最新值

如果启用了缓存(默认),第二次读取的值可能不会变,除非调用 refresh()。

3.6 QString canonicalFilePath() const

功能说明
QFileInfo::canonicalFilePath() 返回文件的真实绝对路径,也就是:

  • 符号链接(软链接)会被解析成真实路径。
  • 返回的是标准化后的绝对路径。
  • 如果文件不存在,则返回空字符串。

示例对比
假设有如下结构(在 Unix 系统上):

/home/user/
├── real_folder/
│   └── data.txt
└── symlink_folder → real_folder(符号链接)
QFileInfo info("/home/user/symlink_folder/data.txt");

qDebug() << info.absoluteFilePath();   // 输出: "/home/user/symlink_folder/data.txt"
qDebug() << info.canonicalFilePath();  // 输出: "/home/user/real_folder/data.txt"

canonicalFilePath() 解析了符号链接,返回了真实文件所在路径。

使用场景

  • 想获取文件的真实位置(比如检测重复文件)
  • 处理符号链接或快捷方式(macOS/Linux 下常用)
  • 用于缓存系统、去重时判断路径是否真的相同

在 Windows 上,如果路径中包含快捷方式或符号链接(如 mklink 创建的软链接),这个方法也会尝试解析真实路径。

如果文件不存在,则返回空字符串:

QFileInfo info("not_exist_file.txt");
qDebug() << info.canonicalFilePath();  // 输出: ""

示例:判断两个路径是否指向同一个文件

QFileInfo a("/home/user/real_folder/data.txt");
QFileInfo b("/home/user/symlink_folder/data.txt");

if (a.canonicalFilePath() == b.canonicalFilePath()) {
    qDebug() << "它们是同一个文件!";
}

3.7 QString completeBaseName() const

功能说明
默认只去掉最后一个扩展名之后的部分。

示例:

QFileInfo info("backup_2024.tar.gz");
qDebug() << "baseName:" << info.baseName();             // "backup_2024"
qDebug() << "completeBaseName:" << info.completeBaseName(); // "backup_2024.tar"

3.8 QString completeSuffix() const

功能说明
会返回文件名中最后一个点 . 之后的所有内容,也就是完整的扩展名,包括多重后缀。
QFileInfo::completeSuffix() 中所谓的“最后一个点”是指:从文件名中找到第一个点之后的所有部分都被认为是完整后缀,而不是字面意义上的“最后一个点”。

假设文件名如下:

QFileInfo file1("report.txt");
QFileInfo file2("archive.tar.gz");
QFileInfo file3("data.backup.meta.json");

在这里插入图片描述

示例代码:

QFileInfo info("project.final.backup.tar.gz");

qDebug() << "fileName:         " << info.fileName();         
qDebug() << "suffix:           " << info.suffix();           
qDebug() << "completeSuffix:   " << info.completeSuffix();    

输出:

fileName:          "project.final.backup.tar.gz"
suffix:            "gz"
completeSuffix:    "final.backup.tar.gz"

总结
在这里插入图片描述

3.9 QDir dir() const

功能说明
QFileInfo::dir() 返回一个 QDir 对象,表示当前文件所属的目录。这个目录是指文件所在的路径部分,不包括文件名本身。
它和 absoluteDir() 的区别是:

QFileInfo info("logs/app/log.txt");

QDir relativeDir = info.dir(); // 相对目录:logs/app
qDebug() << "dir:" << relativeDir.path();

QDir absDir = info.absoluteDir(); // 绝对目录(全路径)
qDebug() << "absoluteDir:" << absDir.absolutePath();

输出:

dir: "logs/app"
absoluteDir: "D:/Code/Qt/QFileInfoDemo/logs/app"

3.9.1 QDateTime birthTime() const

功能说明
QFileInfo::birthTime() 用于返回文件的创建时间(也叫“出生时间”),即文件在文件系统中第一次被创建时的时间戳。
这个时间和文件的:

  • 修改时间 (lastModified())
  • 访问时间 (lastRead())

不同,它表示最原始的创建时间。

注意事项

  • birthTime() 依赖于底层文件系统和操作系统的支持。
  • 在某些平台(如 Linux 上的 ext4)中可能返回无效时间(如空值),因为有的文件系统不存储创建时间。
  • 在 Windows 和 macOS 上通常有效。

示例代码:

QFileInfo info("example.txt");

QDateTime created = info.birthTime();

if (created.isValid()) {
    qDebug() << "文件创建时间:" << created.toString("yyyy-MM-dd hh:mm:ss");
} else {
    qDebug() << "当前平台不支持 birthTime() 或文件无创建时间信息";
}

示例输出(Windows)

文件创建时间: "2024-10-01 14:25:30"

3.9.2 QDateTime lastModified() const

功能说明
返回文件的最后修改时间(Last Modified Time)。也就是说,上一次写入文件内容的时间,不包括读取或访问操作。这是文件时间属性中最常用、兼容性最好的一个,所有主流平台都支持(Windows、Linux、macOS)。

示例代码:

QFileInfo info("example.txt");

QDateTime modified = info.lastModified();

qDebug() << "文件最后修改时间:" << modified.toString("yyyy-MM-dd hh:mm:ss");

输出:

文件最后修改时间: "2024-10-11 18:30:45"

注意事项

  • 修改时间只在文件内容改变时更新,重命名不更新。
  • 返回的是本地时间(可通过 toUTC() 转为 UTC)。
  • 如果文件不存在,返回的 QDateTime 是无效的:isValid() == false

示例:判断文件是否“最近更新”

QFileInfo info("report.txt");

QDateTime last = info.lastModified();
QDateTime now = QDateTime::currentDateTime();

if (last.secsTo(now) < 60 * 60) {
    qDebug() << "文件在1小时内更新过!";
}

3.9.3 QDateTime lastRead() const

功能说明
返回文件的最后访问时间,也就是上一次被“读取”或“打开”的时间,包括:

  • 用户用记事本打开看了下。
  • 程序调用了 QFile::read()、fopen()、QTextStream 等。
  • 使用 cat、more、less 等命令查看

这个时间与文件内容是否修改无关,只要读取就会更新(前提是系统支持)。

注意事项

  • 并不是所有操作系统或文件系统都支持“读取时间”属性!Linux:默认 不更新 atime(为性能考虑,mount 时常用 noatime),而Windows/macOS:大多数情况下支持。
  • 如果不支持,会返回无效的 QDateTime(isValid() == false)

示例代码:

QFileInfo info("data.txt");

QDateTime last = info.lastRead();

if (last.isValid()) {
    qDebug() << "文件最后读取时间:" << last.toString("yyyy-MM-dd hh:mm:ss");
} else {
    qDebug() << "系统不支持 lastRead() 或文件不存在";
}

示例:判断一个文件是否“最近被查看”

QFileInfo info("report.pdf");
QDateTime last = info.lastRead();
QDateTime now = QDateTime::currentDateTime();

if (last.isValid() && last.secsTo(now) < 60 * 10) {
    qDebug() << "文件在最近10分钟被访问过";
}

3.9.4 bool exists() const

功能说明
用于判断当前 QFileInfo 指向的文件或目录是否存在于文件系统中。
它会返回:

  • true → 文件/目录确实存在。
  • false → 不存在,可能是路径错误或还没创建。

该函数同时适用于文件和目录。

示例代码:

QFileInfo fileInfo("data/report.txt");

if (fileInfo.exists()) {
    qDebug() << "文件存在,准备读取!";
} else {
    qDebug() << "文件不存在,请检查路径或文件名。";
}

判断目录是否存在:

QFileInfo dirInfo("logs");

if (dirInfo.exists() && dirInfo.isDir()) {
    qDebug() << "目录存在";
}

3.9.5 QString fileName() const

举例说明:
功能说明
返回当前文件路径中最后的文件名部分,也就是去除路径后的文件名。不包含路径,也不做扩展名截断,保留原样(含后缀)。

QFileInfo info("/home/user/docs/report_2024.pdf");

qDebug() << info.fileName();  // 输出: "report_2024.pdf"

3.9.6 QString filePath() const

功能说明
返回构造这个 QFileInfo 对象时传入的原始路径(原始的字符串形式),也就是文件或目录的路径 + 文件名,不一定是绝对路径。区别在于,它不会自动转换成绝对路径,也不会解析符号链接。

示例代码:

QFileInfo info("data/report.txt");

qDebug() << "filePath:" << info.filePath();             // "data/report.txt"
qDebug() << "absoluteFilePath:" << info.absoluteFilePath(); // "/home/user/project/data/report.txt"

注意事项

  • 如果你传入的是相对路径,filePath() 返回的仍是相对路径。
  • 如果想要做系统层的访问,请优先用 absoluteFilePath() 或 canonicalFilePath()。

3.9.7 QDateTime fileTime(QFile::FileTime time) const

功能说明
fileTime() 是 QFileInfo 提供的一个通用接口,可以传入一个枚举值 QFile::FileTime,它会返回对应的时间。这比分别调用 lastModified()、lastRead()、birthTime() 更加统一和灵活。

可选参数枚举
在这里插入图片描述
示例代码:

QFileInfo info("example.txt");

qDebug() << "创建时间:" << info.fileTime(QFile::BirthTime).toString();
qDebug() << "修改时间:" << info.fileTime(QFile::ModificationTime).toString();
qDebug() << "访问时间:" << info.fileTime(QFile::AccessTime).toString();

3.9.10 bool isAbsolute() const

功能说明
用于判断当前文件路径是否是绝对路径。

  • 返回 true:表示该路径是绝对路径
  • 返回 false:表示该路径是相对路径

注意:这个函数判断的是传给 QFileInfo 的路径是不是绝对的,而不是文件是否真的存在。

示例代码:

QFileInfo info1("/home/user/readme.md");
QFileInfo info2("docs/report.txt");

qDebug() << info1.filePath() << "是否是绝对路径?" << info1.isAbsolute();  // true
qDebug() << info2.filePath() << "是否是绝对路径?" << info2.isAbsolute();  // false

Windows 下类似:

QFileInfo info("C:\\Program Files\\Qt\\qt.conf");
qDebug() << info.isAbsolute();  // true

3.10.1 bool isDir() const

功能说明
用于判断当前 QFileInfo 对象所指的路径是否是一个存在的目录。

  • 返回 true:是一个已存在的目录
  • 返回 false:不是目录,或者目录不存在

它不仅仅判断路径形式,还会检查对应的路径在文件系统中是否存在并是目录。

示例代码:

QFileInfo fileInfo1("/home/user/Documents");
QFileInfo fileInfo2("config/settings.json");

if (fileInfo1.isDir())
    qDebug() << "fileInfo1 是目录";
else
    qDebug() << "fileInfo1 不是目录";

if (!fileInfo2.isDir())
    qDebug() << "fileInfo2 是文件或路径不存在";

与其它函数组合使用
可以搭配 exists() 一起使用,判断路径是否为存在的目录:

QFileInfo info("backup");

if (info.exists() && info.isDir()) {
    qDebug() << "这是一个有效目录";
} else {
    qDebug() << "不是有效目录";
}

3.10.2 bool isExecutable() const

功能说明
用于判断当前文件是否具有可执行权限。

  • 在 Linux/macOS:判断该文件是否有 x 权限(可执行)
  • 在 Windows:判断文件扩展名是否是 .exe、.bat、.com、.cmd 等常见可执行类型

注意:它只判断“是否 可执行”,不判断“是否 存在”,所以建议搭配 exists() 使用。

示例代码:

QFileInfo info1("/usr/bin/python3");
QFileInfo info2("setup.exe");
QFileInfo info3("README.md");

qDebug() << "info1 是可执行文件?" << info1.isExecutable();  // Linux下返回 true
qDebug() << "info2 是可执行文件?" << info2.isExecutable();  // Windows下返回 true
qDebug() << "info3 是可执行文件?" << info3.isExecutable();  // 返回 false

搭配推荐

QFileInfo exeFile("tools/helper.sh");

if (exeFile.exists() && exeFile.isExecutable()) {
    qDebug() << "可以运行的文件:" << exeFile.filePath();
} else {
    qDebug() << "该文件不可执行";
}

3.10.3 bool isFile() const

功能说明
用于判断当前 QFileInfo 对象所代表的路径是否是一个存在的常规文件(不是目录,不是符号链接指向目录,不是设备文件等)。

  • 返回 true:路径存在,且是一个普通文件(如 .txt, .jpg, .exe 等)
  • 返回 false:不存在,或不是文件(例如是目录)

它不仅判断路径格式,还要实际存在且是文件才返回 true。

示例代码:

QFileInfo fileInfo1("example.txt");
QFileInfo fileInfo2("logs/");
QFileInfo fileInfo3("not_exist.txt");

qDebug() << "fileInfo1 是文件?" << fileInfo1.isFile();  // 取决于是否存在
qDebug() << "fileInfo2 是文件?" << fileInfo2.isFile();  // false,如果是目录
qDebug() << "fileInfo3 是文件?" << fileInfo3.isFile();  // false,如果不存在

搭配推荐使用

QFileInfo info("config/settings.ini");

if (info.exists()) {
    if (info.isFile()) {
        qDebug() << "这是一个普通文件";
    } else {
        qDebug() << "路径存在,但不是文件";
    }
} else {
    qDebug() << "文件不存在";
}

3.10.4 bool isHidden() const

功能说明
判断当前路径是否是一个隐藏文件或目录。

  • 在 Windows:是否设置了“隐藏”属性(Hidden attribute)
  • 在 Unix/Linux/macOS:是否以点号 . 开头(例如 .git, .bashrc)

这个方法适用于文件和目录。

示例代码:

QFileInfo fileInfo1(".gitignore");   // Unix系统上是隐藏文件
QFileInfo fileInfo2("normal.txt");   // 普通文件
QFileInfo fileInfo3(".config/");     // 隐藏目录(Unix)

qDebug() << "fileInfo1 是隐藏的?" << fileInfo1.isHidden();  // true
qDebug() << "fileInfo2 是隐藏的?" << fileInfo2.isHidden();  // false
qDebug() << "fileInfo3 是隐藏的?" << fileInfo3.isHidden();  // true

搭配使用示例

QFileInfo info("C:/Users/YourName/AppData");

if (info.exists() && info.isDir()) {
    if (info.isHidden()) {
        qDebug() << "该目录是隐藏的";
    } else {
        qDebug() << "这是一个可见目录";
    }
}

注意事项
Windows 下 .gitignore 不会被视为隐藏,除非文件属性被设置为“隐藏”。

3.10.5 bool isNativePath() const

功能说明
用于判断当前路径是否是一个平台原生路径格式。

  • 返回 true:路径使用的是当前操作系统原生格式(例如 C:\Windows 或 /usr/bin)
  • 返回 false:路径是URL 风格或非本地格式(如 file:///C:/Windows)

举例:
在这里插入图片描述
示例代码:

QFileInfo nativeInfo("C:/Windows/System32");
QFileInfo urlInfo("file:///C:/Windows/System32");
QFileInfo qrcInfo("qrc:/images/icon.png");

qDebug() << nativeInfo.isNativePath();  // true
qDebug() << urlInfo.isNativePath();     // false
qDebug() << qrcInfo.isNativePath();     // false

注意事项

  • 不判断路径是否存在,它只看路径的格式
  • 对于使用 QFileDialog 选择的文件,一般都是 native 路径
  • 如果通过 QUrl::toLocalFile() 处理后再构造 QFileInfo,结果也会是 native

3.10.6 bool isReadable() const

功能说明
判断当前路径所代表的文件或目录是否具有可读权限(对当前用户/进程)。

  • 返回 true:当前用户有读取权限
  • 返回 false:没有读取权限、文件不存在、或者不是有效路径

判断的是操作系统层面的权限,而不是逻辑状态。

示例代码:

QFileInfo fileInfo("/etc/passwd");   // Linux 系统的公共配置文件
QFileInfo fileInfo2("/root/secret.txt"); // 普通用户通常无法读取

qDebug() << fileInfo.isReadable();   // true
qDebug() << fileInfo2.isReadable();  // false(除非你是 root)

搭配推荐

QFileInfo info("user_config.ini");

if (!info.exists()) {
    qDebug() << "文件不存在";
} else if (!info.isReadable()) {
    qDebug() << "文件存在,但不可读";
} else {
    qDebug() << "文件存在且可读";
}

注意事项
在这里插入图片描述
3.10.7 bool isRelative() const

功能说明
用于判断当前路径是否是相对路径。

  • 返回 true:表示路径是相对的(例如:“images/icon.png”、“./data”)
  • 返回 false:表示路径是绝对路径(例如:“C:/Program Files” 或 “/usr/bin”)

注意:这个函数不关心路径是否存在,仅判断路径格式。

判断规则(平台相关):
在这里插入图片描述
示例代码:

QFileInfo info1("test.txt");
QFileInfo info2("C:/Windows/System32");
QFileInfo info3("/usr/local/bin");
QFileInfo info4("./data/file.txt");

qDebug() << info1.filePath() << "是相对路径吗?" << info1.isRelative(); // true
qDebug() << info2.filePath() << "是相对路径吗?" << info2.isRelative(); // false
qDebug() << info3.filePath() << "是相对路径吗?" << info3.isRelative(); // false
qDebug() << info4.filePath() << "是相对路径吗?" << info4.isRelative(); // true

搭配使用建议:

QFileInfo fileInfo("./config/settings.ini");

if (fileInfo.isRelative()) {
    QString absPath = fileInfo.absoluteFilePath();
    qDebug() << "这是相对路径,已转为绝对路径:" << absPath;
} else {
    qDebug() << "这是一个绝对路径:" << fileInfo.filePath();
}

3.10.8 bool isRoot() const

功能说明
用于判断当前路径是否是文件系统的根目录。

  • 返回 true:如果该路径是根目录(如 C:/、/)
  • 返回 false:不是根目录(如 C:/Users、/home/user)

它适用于 Windows、Linux、macOS 等平台:
在这里插入图片描述
搭配推荐使用

QFileInfo info(QDir::currentPath());

if (info.isRoot()) {
    qDebug() << "当前路径是根目录,无法再上移了。";
} else {
    QDir dir = info.dir();
    dir.cdUp();
    qDebug() << "上一级目录是:" << dir.absolutePath();
}

3.10.9 bool isWritable() const

功能说明
判断当前用户对该文件或目录是否具有写入权限。

  • 返回 true:当前用户可以写入(文件可修改或目录可写)
  • 返回 false:没有写权限、只读文件、受权限控制、目录受限等

示例代码:

QFileInfo fileInfo("output.log");

if (fileInfo.exists()) {
    if (fileInfo.isWritable()) {
        qDebug() << fileInfo.fileName() << "可写 ✅";
    } else {
        qDebug() << fileInfo.fileName() << "不可写 ❌";
    }
} else {
    qDebug() << "文件不存在";
}

注意事项
在这里插入图片描述

3.10.10 void refresh()

功能说明
用于强制刷新 QFileInfo 对象内部缓存的信息,使其重新读取磁盘上的实际数据。默认情况下,QFileInfo 会缓存文件信息(如大小、权限、时间戳等),为了提高性能。而 refresh() 就是用于在文件可能已被修改或替换的情况下,手动更新这些信息。

示例代码:

QFileInfo fileInfo("example.txt");

qDebug() << "文件初始大小:" << fileInfo.size();

// 模拟外部修改文件
QFile file("example.txt");
if (file.open(QIODevice::Append)) {
    file.write("Hello Qt!\n");
    file.close();
}

// 此时 fileInfo.size() 仍是旧值
qDebug() << "未刷新前大小:" << fileInfo.size();

// 刷新缓存,再获取新值
fileInfo.refresh();
qDebug() << "刷新后大小:" << fileInfo.size();

使用场景举例:
在这里插入图片描述

注意事项
在这里插入图片描述
3.10.11 void setCaching(bool enable)

功能说明
于设置该 QFileInfo 实例是否使用内部缓存机制来存储文件信息(如是否存在、大小、权限等)。

  • enable == true(默认):启用缓存,访问快,但不会实时反映文件变化。
  • enable == false:关闭缓存,每次调用都会从磁盘重新读取文件状态,确保信息是最新的。

默认行为
QFileInfo 默认启用了缓存(caching = true),为了提升性能。但这意味着:

  • 文件被外部修改后,QFileInfo 的信息可能是过期的;
  • 必须调用 .refresh() 或 .setCaching(false) 来强制读取最新数据。

示例代码:

QFileInfo fileInfo("test.txt");

// 默认启用缓存,修改后 size 可能没变
qDebug() << "默认缓存:" << fileInfo.caching();
qDebug() << "初始大小:" << fileInfo.size();

// 模拟写入新内容
QFile file("test.txt");
if (file.open(QIODevice::Append)) {
    file.write("new line\n");
    file.close();
}

// 强制不缓存,自动读取最新状态
fileInfo.setCaching(false);
qDebug() << "关闭缓存后大小:" << fileInfo.size();

输出:
在这里插入图片描述
常见用途
在这里插入图片描述

注意事项
在这里插入图片描述

3.10.12 void setFile(const QString &file)

功能说明
用于重新设置该 QFileInfo 对象所关联的文件路径,并更新其对应的文件信息(如是否存在、大小、权限、修改时间等)。这相当于“重新指向一个新文件”,类似于重用一个 QFileInfo 对象而不是创建一个新的。

示例代码:

QFileInfo fileInfo;

fileInfo.setFile("file1.txt");
qDebug() << "file1.txt 是否存在?" << fileInfo.exists();

fileInfo.setFile("file2.txt");
qDebug() << "file2.txt 是否存在?" << fileInfo.exists();

使用场景
在这里插入图片描述

注意事项
在这里插入图片描述
3.10.13 void setFile(const QFile &file)

功能说明
使用一个已有的 QFile 对象,来设置(或重设)当前 QFileInfo 实例所关联的文件。

  • 会自动从 QFile 对象中提取其路径(即 QFile::fileName())。
  • 自动更新文件信息缓存(如大小、权限、是否存在等)。
  • 可以用于复用同一个 QFileInfo 对象查看多个文件的属性。

示例代码:

QFile file("example.txt");
QFileInfo info;

info.setFile(file);  // 通过 QFile 设置

qDebug() << "文件名:" << info.fileName();
qDebug() << "是否存在:" << info.exists();
qDebug() << "大小:" << info.size();
qDebug() << "最后修改时间:" << info.lastModified();

上面代码中,即使你没有打开文件,只要 QFile 有路径,QFileInfo 就能读取文件系统信息。

使用场景
在这里插入图片描述

注意事项
在这里插入图片描述

3.10.14 void setFile(const QDir &dir, const QString &file)

功能说明
用一个目录 (QDir) 和一个文件名 (QString) 组合出完整路径,并设置为当前 QFileInfo 实例的目标文件。然后就可以像平常一样调用 .exists()、.size()、.lastModified() 等方法获取信息。
相当于:

QFileInfo info(dir.absoluteFilePath(file));

但用这个函数更清晰,也避免手动拼路径。

示例代码:

QDir dir("/home/user/documents");
QString fileName = "report.pdf";

QFileInfo info;
info.setFile(dir, fileName);

qDebug() << "完整路径:" << info.absoluteFilePath();
qDebug() << "是否存在:" << info.exists();
qDebug() << "大小:" << info.size();

输出示例:

完整路径: "/home/user/documents/report.pdf"
是否存在: true
大小: 204800

注意事项

在这里插入图片描述
3.10.15 qint64 size() const

功能说明
该函数返回与 QFileInfo 关联的文件的 字节数(大小),类型是 qint64(即 64 位整数,支持大文件)。

  • 单位是 字节 (Byte)。
  • 仅在文件存在且是常规文件(而非目录)时有意义。
  • 如果文件不存在或不是普通文件,则返回 0。

示例代码:

QFileInfo info("example.txt");

if (info.exists() && info.isFile()) {
    qDebug() << "文件大小为:" << info.size() << "字节";
} else {
    qDebug() << "文件不存在或不是一个普通文件";
}

注意事项
在这里插入图片描述
3.10.16 QString suffix() const

功能说明
QFileInfo::suffix() 会返回文件名的最后一个点(.)之后的部分,也就是文件的后缀(扩展名),但不包含点号 .。

例如:
在这里插入图片描述

示例代码:

QFileInfo info1("report.docx");
QFileInfo info2("archive.tar.gz");
QFileInfo info3("README");

qDebug() << "report.docx 的后缀:" << info1.suffix();  // 输出: "docx"
qDebug() << "archive.tar.gz 的后缀:" << info2.suffix();  // 输出: "gz"
qDebug() << "README 的后缀:" << info3.suffix();  // 输出: ""

使用场景
在这里插入图片描述

注意事项
在这里插入图片描述

3.10.17 void swap(QFileInfo &other)

功能说明
用于将当前 QFileInfo 对象与另一个 QFileInfo 对象中的所有内容进行高效地互换,无需临时拷贝或额外资源分配。

示例代码:

QFileInfo info1("/home/user/file1.txt");
QFileInfo info2("/home/user/file2.txt");

qDebug() << "交换前:";
qDebug() << "info1:" << info1.filePath();
qDebug() << "info2:" << info2.filePath();

info1.swap(info2);

qDebug() << "交换后:";
qDebug() << "info1:" << info1.filePath();
qDebug() << "info2:" << info2.filePath();

输出结果:

交换前:
info1: "/home/user/file1.txt"
info2: "/home/user/file2.txt"

交换后:
info1: "/home/user/file2.txt"
info2: "/home/user/file1.txt"

注意事项
在这里插入图片描述

四、常用静态函数的介绍和使用

4.1 static bool QFileInfo::exists(const QString &file)

功能说明
这个函数是 静态函数,无需先创建 QFileInfo 对象,就能直接用来判断路径是否存在。你只需要传入一个路径字符串,它会判断:

  • 这个路径是否对应于一个存在的文件或目录。
  • 返回值为 true 表示存在,false 表示不存在。

它比创建 QFileInfo(file).exists() 更简洁。

示例代码:

QString path1 = "/home/user/report.txt";
QString path2 = "C:/Windows/System32";
QString path3 = "nonexistent.file";

if (QFileInfo::exists(path1)) {
    qDebug() << path1 << "存在";
} else {
    qDebug() << path1 << "不存在";
}

if (QFileInfo::exists(path2)) {
    qDebug() << path2 << "存在";
}

if (!QFileInfo::exists(path3)) {
    qDebug() << path3 << "不存在";
}

注意事项
在这里插入图片描述

五、完整代码示例

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>

#include <QLabel>
#include <QLineEdit>
#include <QCheckBox>
#include <QPushButton>

#include <QFileDialog>
#include <QDateTime>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QCheckBox>

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QWidget(parent) {
        this->setWindowTitle("获取文件属性");

        m_pLabelFileName = new QLabel("文件路径名称:", this);
        m_pLineEditFileName = new QLineEdit(this);
        m_pBtnFileName = new QPushButton("打开文件...");
        connect(m_pBtnFileName, &QPushButton::clicked, this, &MainWindow::getFilePathAndName);

        m_pLabelFileSize = new QLabel("文件容量大小:", this);
        m_pLineEditFileSize = new QLineEdit(this);

        m_pLabelFileCreateTime = new QLabel("文件创建时间:", this);
        m_pLineEditFileCreateTime = new QLineEdit(this);

        m_pLabelFileModifyTime = new QLabel("文件修改时间:", this);
        m_pLineEditFileModifyTime = new QLineEdit(this);

        m_pLabelFileAccessTime = new QLabel("文件访问时间:", this);
        m_pLineEditFileAccessTime = new QLineEdit(this);

        m_pLabelFileAttribute = new QLabel("文件属性:", this);
        m_pCheckBoxIsFile = new QCheckBox("文件", this);
        m_pCheckBoxIsHide = new QCheckBox("隐藏属性", this);
        m_pCheckBoxIsReadAble = new QCheckBox("只读属性", this);
        m_pCheckBoxIsWriteAble = new QCheckBox("只写属性", this);
        m_pCheckBoxIsExecute = new QCheckBox("执行权限", this);
        m_pBtnFileAttributeInfo = new QPushButton("获取文件属性的全部数据信息", this);
        connect(m_pBtnFileAttributeInfo, &QPushButton::clicked, this, &MainWindow::getFileattributeInfo);


        QGridLayout *pGLayout = new QGridLayout();
        pGLayout->addWidget(m_pLabelFileName, 0, 0);
        pGLayout->addWidget(m_pLineEditFileName, 0, 1);
        pGLayout->addWidget(m_pBtnFileName, 0, 2);
        pGLayout->addWidget(m_pLabelFileSize, 1, 0);
        pGLayout->addWidget(m_pLineEditFileSize, 1, 1, 1, 2);
        pGLayout->addWidget(m_pLabelFileCreateTime, 2, 0);
        pGLayout->addWidget(m_pLineEditFileCreateTime, 2, 1, 1, 2);
        pGLayout->addWidget(m_pLabelFileModifyTime, 3, 0);
        pGLayout->addWidget(m_pLineEditFileModifyTime, 3, 1, 1, 2);
        pGLayout->addWidget(m_pLabelFileAccessTime, 4, 0);
        pGLayout->addWidget(m_pLineEditFileAccessTime, 4, 1, 1, 2);

        // 水平布局
        QHBoxLayout *pHlayout = new QHBoxLayout();
        pHlayout->addWidget(m_pLabelFileAttribute);
        pHlayout->addStretch();

        QHBoxLayout *pHlayoutat = new QHBoxLayout();
        pHlayoutat->addWidget(m_pCheckBoxIsFile);
        pHlayoutat->addWidget(m_pCheckBoxIsHide);
        pHlayoutat->addWidget(m_pCheckBoxIsReadAble);
        pHlayoutat->addWidget(m_pCheckBoxIsWriteAble);
        pHlayoutat->addWidget(m_pCheckBoxIsExecute);

        QHBoxLayout *pHlayoutbtn = new QHBoxLayout();
        pHlayoutbtn->addWidget(m_pBtnFileAttributeInfo);

        // 垂直布局
        QVBoxLayout *pVlayout = new QVBoxLayout(this);
        pVlayout->addLayout(pGLayout);
        pVlayout->addLayout(pHlayout);
        pVlayout->addLayout(pHlayoutat);
        pVlayout->addLayout(pHlayoutbtn);
    }

private slots:
    void getFilePathAndName() {
        QString strFileNamePath;
        strFileNamePath = QFileDialog::getOpenFileName(this, "打开文件对话框", "/", "files(*)");
        m_pLineEditFileName->setText(strFileNamePath);
    }

    void getFileattributeInfo() {
        QString strFile = m_pLineEditFileName->text();
        QFileInfo fileInfo(strFile);

        qint64 fileSize = fileInfo.size(); //获取文件容量大小
        QDateTime createTime = fileInfo.birthTime(); //文件创建时间
        QDateTime lastModifyTime = fileInfo.lastModified(); //最后修改时间
        QDateTime lastAccessTime = fileInfo.lastRead(); //最后访问时间

        bool bFile = fileInfo.isFile();
        bool bHide = fileInfo.isHidden();
        bool bRead = fileInfo.isReadable();
        bool bWrite = fileInfo.isWritable();
        bool bExecute = fileInfo.isExecutable();

        m_pLineEditFileSize->setText(QString::number(fileSize));
        m_pLineEditFileCreateTime->setText(createTime .toString());
        m_pLineEditFileModifyTime->setText(lastModifyTime.toString());
        m_pLineEditFileAccessTime->setText(lastAccessTime.toString());

        m_pCheckBoxIsFile->setCheckState(bFile ? Qt::Checked : Qt::Unchecked);
        m_pCheckBoxIsHide->setCheckState(bHide ? Qt::Checked : Qt::Unchecked);
        m_pCheckBoxIsReadAble->setCheckState(bRead ? Qt::Checked : Qt::Unchecked);
        m_pCheckBoxIsWriteAble->setCheckState(bWrite ? Qt::Checked : Qt::Unchecked);
        m_pCheckBoxIsExecute->setCheckState(bExecute ? Qt::Checked : Qt::Unchecked);
    }

private:
    QLabel *m_pLabelFileName;
    QLineEdit *m_pLineEditFileName;
    QPushButton *m_pBtnFileName;

    // 文件容量大小
    QLabel *m_pLabelFileSize;
    QLineEdit *m_pLineEditFileSize;

    // 文件创建时间
    QLabel *m_pLabelFileCreateTime;
    QLineEdit *m_pLineEditFileCreateTime;

    // 文件修改时间
    QLabel *m_pLabelFileModifyTime;
    QLineEdit *m_pLineEditFileModifyTime;

    // 文件访问时间
    QLabel *m_pLabelFileAccessTime;
    QLineEdit *m_pLineEditFileAccessTime;

    // 文件属性及复选控件
    QLabel *m_pLabelFileAttribute;
    QCheckBox *m_pCheckBoxIsFile;
    QCheckBox *m_pCheckBoxIsHide;
    QCheckBox *m_pCheckBoxIsReadAble;
    QCheckBox *m_pCheckBoxIsWriteAble;
    QCheckBox *m_pCheckBoxIsExecute;
    QPushButton *m_pBtnFileAttributeInfo;
};
#endif // MAINWINDOW_H

输出结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值