Qt QFileInfo 类技术讲解

QFileInfo 类概述

QFileInfo 是 Qt 框架中一个超级重大的类,它提供了访问文件系统中文件属性的接口。通过 QFileInfo ,开发者可以获取文件的各种元数据信息,而无需实际打开或读取文件内容。这使得文件信息的查询变得高效且便捷。

核心功能

QFileInfo 提供了以下主要功能:

  1. 文件基本属性 :文件名、路径、后缀等

  2. 文件大小信息 :获取文件大小(字节数)

  3. 时间信息 :创建时间、最后修改时间、最后访问时间

  4. 文件类型判断 :是否为目录、文件、符号链接等

  5. 权限信息 :读、写、执行权限检查

  6. 所有权信息 :文件所有者和组信息

代码示例:文件信息查看器

下面是一个完整的示例,展示如何使用 QFileInfo 类获取和显示文件的详细信息:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

classFileInfoViewer:publicQMainWindow {
Q_OBJECT

public:
FileInfoViewer(QWidget *parent =ptr) : QMainWindow(parent) {
setupUI;
setWindowTitle("Qt文件信息查看器");
resize(700,600);
}

privateslots:
voidonSelectFile {
QString filePath = QFileDialog::getOpenFileName(this, "选择文件");
if(!filePath.isEmpty) {
displayFileInfo(filePath);
}
}

voidonOpenFile {
if(!currentFilePath.isEmpty) {
QDesktopServices::openUrl(QUrl::fromLocalFile(currentFilePath));
}
}

voidonOpenContainingFolder {
if(!currentFilePath.isEmpty) {
QFileInfoinfo(currentFilePath);
QDesktopServices::openUrl(QUrl::fromLocalFile(info.path));
}
}

private:
voidsetupUI {
QWidget *centralWidget =newQWidget(this);
setCentralWidget(centralWidget);

QVBoxLayout *mainLayout =newQVBoxLayout(centralWidget);

// 文件选择区域
QHBoxLayout *fileSelectionLayout =newQHBoxLayout;
QPushButton *selectFileBtn =newQPushButton("选择文件");
filePathLabel =newQLabel("未选择文件");
filePathLabel->setWordWrap(true);
filePathLabel->setStyleSheet("QLabel { background-color: #f0f0f0; padding: 5px; }");

fileSelectionLayout->addWidget(selectFileBtn);
fileSelectionLayout->addWidget(filePathLabel,1);

// 信息显示区域
infoTable =newQTableWidget;
infoTable->setColumnCount(2);
infoTable->setHorizontalHeaderLabels(QStringList "属性" "值");
infoTable->horizontalHeader->setStretchLastSection(true);
infoTable->verticalHeader->setVisible(false);
infoTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
infoTable->setSelectionBehavior(QAbstractItemView::SelectRows);

// 操作按钮区域
QHBoxLayout *buttonLayout =newQHBoxLayout;
QPushButton *openFileBtn =newQPushButton("打开文件");
QPushButton *openFolderBtn =newQPushButton("打开所在文件夹");

buttonLayout->addWidget(openFileBtn);
buttonLayout->addWidget(openFolderBtn);
buttonLayout->addStretch;

mainLayout->addLayout(fileSelectionLayout);
mainLayout->addWidget(infoTable,1);
mainLayout->addLayout(buttonLayout);

// 连接信号槽
connect(selectFileBtn, &QPushButton::clicked,this, &FileInfoViewer::onSelectFile);
connect(openFileBtn, &QPushButton::clicked,this, &FileInfoViewer::onOpenFile);
connect(openFolderBtn, &QPushButton::clicked,this, &FileInfoViewer::onOpenContainingFolder);
}

voiddisplayFileInfo(constQString &filePath) {
currentFilePath = filePath;
filePathLabel->setText(filePath);

QFileInfoinfo(filePath);

// 清空表格
infoTable->setRowCount(0);

// 检查文件是否存在
if(!info.exists) {
addTableRow("状态", "文件不存在");
return;
}

// 添加文件信息到表格
addTableRow("文件名", info.fileName);
addTableRow("完整路径", info.absoluteFilePath);
addTableRow("目录", info.path);
addTableRow("绝对目录", info.absolutePath);
addTableRow("规范路径", info.canonicalFilePath);

// 文件大小
qint64 size = info.size;
QString sizeStr;
if(size1024) {
sizeStr = QString("%1 字节").arg(size);
}elseif(size1024*1024) {
sizeStr = QString("%1 KB (%2 字节)").arg(size /1024.0,0, 'f',2).arg(size);
}elseif(size1024*1024*1024) {
sizeStr = QString("%1 MB (%2 字节)").arg(size / (1024.0*1024.0),0, 'f',2).arg(size);
}else{
sizeStr = QString("%1 GB (%2 字节)").arg(size / (1024.0*1024.0*1024.0),0, 'f',2).arg(size);
}
addTableRow("文件大小", sizeStr);

// 文件类型
QString typeStr;
if(info.isDir) {
typeStr = "目录";
}elseif(info.isFile) {
typeStr = "文件";
}elseif(info.isSymLink) {
typeStr = "符号链接";
addTableRow("链接目标", info.symLinkTarget);
}elseif(info.isBundle) {
typeStr = "Bundle (macOS)";
}else{
typeStr = "未知类型";
}
addTableRow("文件类型", typeStr);

// 时间信息
addTableRow("创建时间", info.birthTime.toString("yyyy-MM-dd hh:mm:ss"));
addTableRow("最后修改", info.lastModified.toString("yyyy-MM-dd hh:mm:ss"));
addTableRow("最后访问", info.lastRead.toString("yyyy-MM-dd hh:mm:ss"));

// 权限信息
QString permissions;
if(info.isReadable) permissions += "读 ";
if(info.isWritable) permissions += "写 ";
if(info.isExecutable) permissions += "执行 ";
addTableRow("权限", permissions.isEmpty ? "无" : permissions);

// 所有权信息
addTableRow("所有者", info.owner);
addTableRow("所有者ID", QString::number(info.ownerId));
addTableRow("用户组", info.group);
addTableRow("用户组ID", QString::number(info.groupId));

// 其他属性
addTableRow("是否隐藏", info.isHidden ? "是" : "否");
addTableRow("是否根目录", info.isRoot ? "是" : "否");

// 调整列宽
infoTable->resizeColumnToContents(0);
}

voidaddTableRow(constQString &property,constQString &value) {
introw = infoTable->rowCount;
infoTable->insertRow(row);

QTableWidgetItem *propertyItem =newQTableWidgetItem(property);
QTableWidgetItem *valueItem =newQTableWidgetItem(value);

propertyItem->setFlags(propertyItem->flags & ~Qt::ItemIsEditable);
valueItem->setFlags(valueItem->flags & ~Qt::ItemIsEditable);

infoTable->setItem(row,0, propertyItem);
infoTable->setItem(row,1, valueItem);
}

private:
QLabel *filePathLabel;
QTableWidget *infoTable;
QString currentFilePath;
};

intmain(intargc,char*argv[]) {
QApplicationapp(argc, argv);

FileInfoViewer viewer;
viewer.show;

returnapp.exec;
}

#include"main.moc"

关键技术点详解

1. 创建 QFileInfo 对象

QFileInfo info(filePath);

通过文件路径创建 QFileInfo 对象,这是获取文件信息的第一步。

2. 检查文件是否存在

if(!info.exists) {
addTableRow("状态", "文件不存在");
return;
}

使用 exists 方法检查文件是否存在,避免对不存在的文件进行操作。

3. 获取文件路径信息

addTableRow("文件名", info.fileName);
addTableRow("完整路径", info.absoluteFilePath);
addTableRow("目录", info.path);
addTableRow("绝对目录", info.absolutePath);
addTableRow("规范路径", info.canonicalFilePath);

QFileInfo 提供了多种方法获取文件路径的不同表明形式:

  • fileName :获取文件名(含扩展名)

  • absoluteFilePath :获取绝对路径(含文件名)

  • path :获取文件所在目录的相对路径

  • absolutePath :获取文件所在目录的绝对路径

  • canonicalFilePath :获取规范化的绝对路径(解析所有符号链接)

4. 获取文件大小

qint64 size = info.size;

使用 size 方法获取文件大小(字节数)。示例中还展示了如何将字节数转换为更易读的格式(KB、MB、GB)。

5. 判断文件类型

if(info.isDir) {
typeStr = "目录";
}elseif(info.isFile) {
typeStr = "文件";
}elseif(info.isSymLink) {
typeStr = "符号链接";
addTableRow("链接目标", info.symLinkTarget);
}

QFileInfo 提供了多种方法判断文件类型:

  • isDir :是否为目录

  • isFile :是否为普通文件

  • isSymLink :是否为符号链接

  • isBundle :是否为 Bundle(macOS 特定)

对于符号链接,可以使用 symLinkTarget 方法获取链接指向的实际路径。

6. 获取时间信息

addTableRow("创建时间", info.birthTime.toString("yyyy-MM-dd hh:mm:ss"));
addTableRow("最后修改", info.lastModified.toString("yyyy-MM-dd hh:mm:ss"));
addTableRow("最后访问", info.lastRead.toString("yyyy-MM-dd hh:mm:ss"));

QFileInfo 提供了三种时间信息:

  • birthTime :文件创建时间

  • lastModified :文件最后修改时间

  • lastRead :文件最后访问时间

这些方法返回 QDateTime 对象,可以使用 toString 方法格式化为字符串。

7. 获取权限信息

if(info.isReadable) permissions += "读 ";
if(info.isWritable) permissions += "写 ";
if(info.isExecutable) permissions += "执行 ";

QFileInfo 提供了检查文件权限的方法:

  • isReadable :是否可读

  • isWritable :是否可写

  • isExecutable :是否可执行

8. 获取所有权信息

addTableRow("所有者", info.owner);
addTableRow("所有者ID", QString::number(info.ownerId));
addTableRow("用户组", info.group);
addTableRow("用户组ID", QString::number(info.groupId));

QFileInfo 提供了获取文件所有权信息的方法:

  • owner :文件所有者用户名

  • ownerId :文件所有者用户ID

  • group :文件所属组名

  • groupId :文件所属组ID

9. 其他属性

addTableRow("是否隐藏", info.isHidden ? "是" : "否");
addTableRow("是否根目录", info.isRoot ? "是" : "否");

QFileInfo 还提供了其他有用的方法:

  • isHidden :是否为隐藏文件

  • isRoot :是否为根目录

实际应用场景

  1. 文件管理器 :显示文件的详细信息,如大小、修改时间等

  2. 文件搜索工具 :根据文件属性(大小、修改时间等)过滤搜索结果

  3. 备份工具 :检查文件是否已修改,决定是否需要备份

  4. 权限管理工具 :检查和管理文件权限

  5. 文件同步工具 :比较文件的修改时间,决定是否需要同步

注意事项

  1. 性能思考 QFileInfo 的操作一般涉及文件系统访问,频繁调用可能会影响性能

  2. 缓存机制 QFileInfo 会缓存文件信息,如果需要获取最新信息,可以调用 refresh 方法

  3. 符号链接 :某些方法(如 canonicalFilePath() )会解析符号链接,而其他方法(如 isSymLink() )则不会

  4. 跨平台差异 :某些文件属性在不同操作系统上可能表现不同,如所有权信息在 Windows 和 Unix 系统上的表明方式不同

总结

QFileInfo 是 Qt 框架中一个功能强劲的类,提供了丰富的接口用于获取文件系统中文件的各种属性信息。通过使用 QFileInfo ,开发者可以轻松实现文件信息的查询和显示功能,而无需直接操作文件内容。在实际应用中,合理使用 QFileInfo 可以大大简化文件操作相关的开发工作。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容