C++ Qt开发:QFileSystemWatcher文件监视组件

2024-03-09 01:04

本文主要是介绍C++ Qt开发:QFileSystemWatcher文件监视组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QFileSystemWatcher组件实现对文件或目录的监视功能。

QFileSystemWatcher 是 Qt 框架中提供的一个类,用于监视文件系统中的文件和目录的变化。它允许你在文件或目录发生变化时接收通知,并可以用于监视文件的创建、删除、重命名以及内容修改等操作。这对于需要实时监控文件系统变化的应用程序是非常有用的。

下面是关于 QFileSystemWatcher 类的一些常用函数的解释:

函数描述
QFileSystemWatcher(QObject *parent = nullptr)构造函数,创建一个文件系统监视器对象。
void addPath(const QString &path)添加要监视的文件或目录路径。
void addPaths(const QStringList &paths)添加要监视的多个文件或目录路径。
bool removePath(const QString &path)移除要监视的文件或目录路径。
void removePaths(const QStringList &paths)移除要监视的多个文件或目录路径。
bool contains(const QString &path) const检查监视器是否包含指定的文件或目录路径。
QStringList files() const返回当前监视的文件路径列表。
QStringList directories() const返回当前监视的目录路径列表。
void setFilter(QFileSystemWatcher::Filter filter)设置监视器的过滤器,用于指定要监视的事件类型。
QFileSystemWatcher::Filter filter() const返回监视器当前的过滤器设置。
void fileChanged(const QString &path)信号,当监视的文件发生变化时发出。
void directoryChanged(const QString &path)信号,当监视的目录发生变化时发出。

这些函数允许你动态地添加或移除要监视的文件或目录,设置过滤器以确定要监视的事件类型,并连接相应的信号以处理文件系统的变化事件。

首先我们需要新增一个filesystem.h头文件,该类主要用于实现对文件访问的封装,其中addWatchPath用于增加一个被监控目录,当目录被更新世则调用directoryUpdated,文件被修改调用fileUpdated

#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#include <QObject>
#include <QMap>
#include <QString>
#include <QMap>
#include <QFileSystemWatcher>class FileSystemWatcher : public QObject
{Q_OBJECTpublic:static void addWatchPath(QString path);public slots:// 目录更新时调用void directoryUpdated(const QString &path);// 文件被修改时调用void fileUpdated(const QString &path);private:explicit FileSystemWatcher(QObject *parent = 0);private:// 单例static FileSystemWatcher *m_pInstance;// QFileSystemWatcher变量QFileSystemWatcher *m_pSystemWatcher;// 当前每个监控的内容目录列表QMap<QString, QStringList> m_currentContentsMap;
};#endif // FILESYSTEM_H

接着是filesystem.cpp主函数部分,首先FileSystemWatcher::addWatchPath用于增加一个监控目录。这里的重点在于创建两个信号,当m_pSystemWatcher收到监控数据时,我们让其分别去触发directoryChangedfileChanged两个信号,在信号中分别携带一个参数传递给directoryUpdatedfileUpdated槽函数上进行处理,如果是目录则保存目录中的内容。

void FileSystemWatcher::addWatchPath(QString path)
{qDebug() << QString("添加监控目录: %1").arg(path);if (m_pInstance == NULL){m_pInstance = new FileSystemWatcher();m_pInstance->m_pSystemWatcher = new QFileSystemWatcher();// 连接QFileSystemWatcher的directoryChanged和fileChanged信号到相应的槽connect(m_pInstance->m_pSystemWatcher, SIGNAL(directoryChanged(QString)), m_pInstance, SLOT(directoryUpdated(QString)));connect(m_pInstance->m_pSystemWatcher, SIGNAL(fileChanged(QString)), m_pInstance, SLOT(fileUpdated(QString)));}// 添加监控路径m_pInstance->m_pSystemWatcher->addPath(path);// 如果添加路径是一个目录,保存当前内容列表QFileInfo file(path);if (file.isDir()){const QDir dirw(path);m_pInstance->m_currentContentsMap[path] = dirw.entryList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst);}
}

接着是FileSystemWatcher::directoryUpdated函数的实现部分,如下所示代码,通过QFileSystemWatcher来监听指定目录下文件和子目录的变化。当目录发生变化时,调用directoryUpdated槽函数,比较最新的目录内容和之前保存的内容,找出新增文件、删除文件以及文件重命名等变化。

  • 功能概述
    1. 添加监控路径:通过addWatchPath函数添加监控路径,创建QFileSystemWatcher对象并连接相关信号和槽。
    2. 目录更新处理:当监控的目录发生变化时,调用directoryUpdated槽函数。
    3. 内容变化比较:比较最新的目录内容和之前保存的内容,找出新增文件、删除文件和文件重命名等变化。
    4. 文件重命名处理:如果有文件重命名,输出文件重命名的信息。
    5. 新增文件处理:输出新建文件的信息,并可以在相应的逻辑中处理每个新文件。
    6. 删除文件处理:输出删除文件的信息,并可以在相应的逻辑中处理每个被删除的文件。

代码对文件系统的变化进行了细致的监控和处理,可以用于实时监控目录下文件的变动情况,例如新增文件、删除文件和文件重命名等操作。当用户需要自定义功能时可以在信息输出前对特定目录做进一步处理以达到监视并控制特定文件的功能。

// 任何监控的目录更新(添加、删除、重命名)则调用
void FileSystemWatcher::directoryUpdated(const QString &path)
{qDebug() << QString("目录更新: %1").arg(path);// 比较最新的内容和保存的内容找出区别(变化)QStringList currEntryList = m_currentContentsMap[path];const QDir dir(path);QStringList newEntryList = dir.entryList(QDir::NoDotAndDotDot  | QDir::AllDirs | QDir::Files, QDir::DirsFirst);QSet<QString> newDirSet = QSet<QString>::fromList(newEntryList);QSet<QString> currentDirSet = QSet<QString>::fromList(currEntryList);// 添加了文件QSet<QString> newFiles = newDirSet - currentDirSet;QStringList newFile = newFiles.toList();// 文件已被移除QSet<QString> deletedFiles = currentDirSet - newDirSet;QStringList deleteFile = deletedFiles.toList();// 更新当前设置m_currentContentsMap[path] = newEntryList;if (!newFile.isEmpty() && !deleteFile.isEmpty()){// 文件/目录重命名if ((newFile.count() == 1) && (deleteFile.count() == 1)){qDebug() << QString("文件重命名 %1 到 %2").arg(deleteFile.first()).arg(newFile.first());}}else{// 添加新文件/目录至Dirif (!newFile.isEmpty()){qDebug() << "新建文件或目录: " << newFile;foreach (QString file, newFile){// 处理操作每个新文件....}}// 从Dir中删除文件/目录if (!deleteFile.isEmpty()){qDebug() << "删除文件或目录: " << deleteFile;foreach(QString file, deleteFile){// 处理操作每个被删除的文件....}}}
}

同理,当文件被修改时则调用fileUpdated函数,只需要去除绝对路径与文件名即可,如下代码所示;

void FileSystemWatcher::fileUpdated(const QString &path)
{QFileInfo file(path);QString strPath = file.absolutePath();QString strName = file.fileName();qDebug() << QString("文件 %1 路径 %2 修改").arg(strName).arg(strPath);
}

你可以自行运行课件FileSystemWatcher.zip来观察监控效果,如下图;

这篇关于C++ Qt开发:QFileSystemWatcher文件监视组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/789041

相关文章

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决