Qt文件系统源码分析—第八篇QFileSystemWatcher

news2024/11/26 10:36:17

深度

本文主要分析Windows平台,Mac、Linux暂不涉及

本文只分析到Win32 API/Windows Com组件/STL库函数层次,再下层代码不做探究

本文QT版本5.15.2

类关系图

QTemporaryFile继承QFile

QFile、QSaveFile继承QFileDevice

QFileDevice继承QIODevice

QIODevice、QFileSystemWatcher继承QObject

QLockFile、QFileInfo、QDir、QFileSelector无任何继承关系

QObject中有一指向QObjectData指针d_ptr。d_ptr是保护成员变量,这意味着每个子类可以修改d_ptr内容。在QObject中d_ptr指向QObjectPrivate,

QIODevice中d_ptr指向QIODevicePrivate

QFileDevice中d_ptr指向QFileDevicePrivate

QFile中d_ptr指向QFilePrivate

QTemporaryFile中d_ptr指向QTemporaryFilePrivate

QFileInfo、QDir、QLockFile不继承QObject,因此没有指向QObjectData指针d_ptr。但是各自同样声明了d_ptr变量指向各自的private类

QFileInfo中d_ptr指向QFileInfoPrivate

QDir中d_ptr指向QDirPrivate

QLockFile中d_ptr指向QLockFilePrivate

启发:

这种Private类书写方式适合场景是导出接口稳定、不想公开内部实现细节、内部能够灵活修改

可以用在付费插件、软件逆向等使用场景

QFileSystemWatcher

作用

监视文件夹或者文件

原理

在内部创建监视线程,等Windows操作系统发送目标变更事件后,读取事件解析后发出文件删除、更改等信号。

使用示例

XFileSystemWatcher.h:

#pragma once

#include <QObject>

#include <QMap>

#include <QFileSystemWatcher>

class XFileSystemWatcher : public QObject

{

Q_OBJECT

public:

static void addWatchPath(QString path);

static void clean();

public slots:

// 目录更新时调用,path是监控的路径

void directoryUpdated(const QString& path);

// 文件被修改时调用,path是监控的路径

void fileUpdated(const QString& path);

private:

explicit XFileSystemWatcher(QObject* parent = 0);

private:

static XFileSystemWatcher* m_pInstance;

QFileSystemWatcher* m_pSystemWatcher;

// 当前每个监控的内容目录列表

QMap<QString, QStringList> m_currentContentsMap;

};

XFileSystemWatcher.cpp

#include <QDir>

#include <QFileInfo>

#include <qDebug>

#include <qglobalstatic>

#include "XFileSystemWatcher.h"

XFileSystemWatcher* XFileSystemWatcher::m_pInstance = NULL;

//Q_GLOBAL_STATIC(QFileSystemWatcher, hxTest);

XFileSystemWatcher::XFileSystemWatcher(QObject* parent)

: QObject(parent)

{}

// 监控文件或目录

void XFileSystemWatcher::addWatchPath(QString path)

{

qDebug() << QString("Add to watch: %1").arg(path);

if (m_pInstance == NULL)

{

m_pInstance = new XFileSystemWatcher();

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);

}

}

void XFileSystemWatcher::clean()

{

delete m_pInstance->m_pSystemWatcher;

m_pInstance->m_pSystemWatcher = new QFileSystemWatcher();

}

// 只要任何监控的目录更新(添加、删除、重命名),就会调用。

void XFileSystemWatcher::directoryUpdated(const QString& path)

{

qDebug() << QString("Directory updated: %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("File Renamed from %1 to %2").arg(deleteFile.first()).arg(newFile.first());

}

}

else

{

// 添加新文件/目录至Dir

if (!newFile.isEmpty())

{

qDebug() << "New Files/Dirs added: " << newFile;

foreach(QString file, newFile)

{

// 处理操作每个新文件....

}

}

// 从Dir中删除文件/目录

if (!deleteFile.isEmpty())

{

qDebug() << "Files/Dirs deleted: " << deleteFile;

foreach(QString file, deleteFile)

{

// 处理操作每个被删除的文件....

}

}

}

}

// 文件修改时调用

void XFileSystemWatcher::fileUpdated(const QString& path)

{

QFileInfo file(path);

QString strPath = file.absolutePath();

QString strName = file.fileName();

qDebug() << QString("The file %1 at path %2 is updated").arg(strName).arg(strPath);

}

Main.cpp

#include <QCoreApplication>

#include "XFileSystemWatcher.h"

int main(int argc, char* argv[])

{

QCoreApplication a(argc, argv);

XFileSystemWatcher::addWatchPath("D:/360");

return a.exec();

}

主要函数调用流程及原理

QFileSystemWatcher::addPath

使用API函数FindFirstChangeNotification、FindNextChangeNotification进行监视。

写到最后

目前先写到这,诸位无论是有什么意见或建议都可以写到评论区,下来一起探讨

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/587414.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RK最强ARM系列之RK3588+AI+Ethercat(linux +xenomai+igh)实时解决方案

RK3588是瑞芯微新一代旗舰级高端处理器&#xff0c;具有高算力、低功耗、超强多媒体、丰富数据接口等特点。搭载四核A76四核A55的八核CPU和ARM G610MP4 GPU&#xff0c;内置6.0TOPs算力的NPU。 有五大技术优势 1. 内置多种功能强大的嵌入式硬件引擎&#xff0c;支持8K60fps 的…

5.29-kubernetes learning

文章目录 HomeGet StartedThe kubernetes network model First of all &#xff0c;we should understand the layout of this official website page. Home The Home chapter is that the official website has manuals for different versions of k8s ,and then generally…

chatgpt赋能python:Python中单词排序的方法—从入门到精通

Python中单词排序的方法—从入门到精通 Python是一门很流行的编程语言&#xff0c;它是一门被广泛使用的高级编程语言&#xff0c;为开发者提供了丰富的工具和库&#xff0c;在处理字符串、文本信息时也有着广泛的应用。本文主要介绍在Python中进行单词排序的方法。 什么是单…

python pycharm的安装教程

pycharm安装教程&#xff0c;超详细_皮小孩ls的博客-CSDN博客目录 前言 python的安装教程&#xff1a; 1.下载地址&#xff1a; 2. 安装 1&#xff09;customize installation 勾选 use 2&#xff09;.默认 . 3&#xff09;. 选择安装位置 4&#xff09;.耐心等待&…

【CSSpart4--盒子模型】

CSSpart4--盒子模型 网页布局的三大核心&#xff1a;盒子模型&#xff0c;浮动&#xff0c;定位网页布局的过程&#xff08;本质&#xff09;&#xff1a;盒子模型的组成四部分&#xff1a;边框&#xff0c;内容&#xff0c;内边距&#xff0c;外边距 一 、盒子边框border:1.1 …

Queue 队列的实现与应用

目录 1.概念2.常用的队列方法2.1 方法2.2 代码 3.自己实现队列3.1 构造MyQueue3.2 入队列offer()3.3 出队列poll()3.4 获得队头peek()3.5 是否为空isEmpty()3.6 获得队列大小size() 4.循环队列4.1 概念4.2 解析4.3 如何判断队列满4.4 代码&#xff08;保留一个位置实现&#xf…

vue+nodejs校园二手物品交易市场网站_xa1i4

。为满足如今日益复杂的管理需求&#xff0c;各类管理系统程序也在不断改进。本课题所设计的校园二手交易市场&#xff0c;使用vue框架&#xff0c;Mysql数据库、nodejs语言进行开发&#xff0c;它的优点代码不能从浏览器查看&#xff0c;保密性非常好&#xff0c;比其他的管理…

轻松实现动态人脸识别,AidLux加速智慧城市场景化应用落地

随着AI技术进入全新发展阶段&#xff0c;智能物联网&#xff08;AIoT&#xff09;的渗透率进一步加深&#xff0c;应用场景不断拓展&#xff0c;人脸识别也迅速走进了人们的日常生活&#xff0c;在手机解锁、公司考勤、支付验证、天网抓捕在逃嫌犯等场景中发挥着重要作用。 人脸…

dataV教程-浅用dataV

一别多日&#xff0c;好久没有和大家相见了。其一的原因是因为公司的项目&#xff0c;其二就是因为太懒了。现在给大家浅浅的介绍一下这个好用的大屏展示框架吧。如果后续有深入的话&#xff0c;我会出一个详解版本的。 一、dataV介绍 前言:由于当前的大数据时代&#xff0c;…

Github标星60K!mall前台商城系统正式发布,支持完整订单流程!

之前有很多小伙伴问我&#xff0c;mall项目有没有前台商城系统&#xff0c;可见大家对mall项目的前台商城系统还是非常期待的。最近抽空把前台商城系统的功能给完善了&#xff0c;目前已经可以支持完整的订单流程。我已经把前台商城系统开源了&#xff0c;项目地址也放在文末了…

重磅发布!面向装备制造业服务化转型白皮书(私信获取)

《面向装备制造业服务化转型白皮书》 关于白皮书 《面向装备制造业服务化转型白皮书》通过调研160余家装备制造企业的服务化路径及模式&#xff0c;研讨支持企业开展服务型制造的系统化方案&#xff0c;希望为装备制造业服务化转型&#xff0c;探索切实有效的路径以供参考。 …

【MySQL】- 02 MySQL explain执行

目录 1.使用explain语句去查看分析结果2.MYSQL中的组合索引3.使用慢查询分析&#xff08;实用&#xff09;4.MYISAM和INNODB的锁定explain用法详解关于MySQL执行计划的局限性&#xff1a;备注&#xff1a; 1.使用explain语句去查看分析结果 如explain select * from test1 whe…

nSoftware IPWorks 2022 C++ Crack

nSoftware IPWorks 2022 C最全面的互联网组件套件&#xff0c;PKI 代理远程签署代码和文档&#xff0c;无需暴露您的私钥&#xff0c;一种安全的自托管解决方案&#xff0c;可使用集中存储的密钥实现远程代码和文档签名&#xff0c;随附的 PKCS#11 驱动程序允许与 Jarsigner、S…

小航助学题库蓝桥杯stem科技素养模拟练习试卷(中级第2套)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSDN博客 25. 2020 年 7 月 23 日&#xff0c;中国的火星探测器“天问一号“发射&#xff0c;开始了前往火星的 旅程。作为中国首个完全自主研发…

Vue之条件渲染

1. if分支结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-widt…

【分享】如何国内免费使用ChatGPT4教程

一、ChatGPT-3使用 1、ChatGPT用法总结&#xff1a; 自动化文本生成&#xff1a;可以用GPT生成文章、新闻、文本摘要&#xff0c;甚至小说、诗歌等文学作品。语音生成&#xff1a;结合语音合成技术&#xff0c;GPT可以生成自然流畅的语音&#xff0c;可以用于语音助手、交互式…

Python学习——数据排序及分箱pd.cut\pd.qcut

文章目录 1 排序1.1 按照索引排序 df.sort_index1.2 按照值进行排序 df.sort_values1.3 数值型数据快速排序 df.nlargest 2 分箱&#xff08;离散化&#xff09;2.1 pd.cut2.1.1 均匀切分,等距分箱2.1.2 指定切分点切分 2.2 pd.qcut 1 排序 dataFrame进行排序时&#xff0c;可…

最全面的WMS系统选购指南:从功能到价格一网打尽

WMS&#xff08;仓库管理系统&#xff09;是一款能够提高仓储和物流企业效率的重要工具&#xff0c;并且能够帮助客户更好地管理他们的供应链网络。但是市面上有很多不同的WMS系统&#xff0c;如何选出最适合自己的系统呢&#xff1f;下面将为您介绍全面的WMS系统选购指南。 功…

软件工程师,不懂点设计模式怎么行

设计模式的圣经 提起设计模式&#xff0c;就不得不提《设计模式——可复用面向对象软件的基础》这本经典著作。1995年&#xff0c;GOF&#xff08;Gang Of Four&#xff09;&#xff0c;也就是Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides这四个人&#xff0c;合…

感谢你们为科技创新和社会进步做出的贡献

感谢你们为科技创新和社会进步做出的贡献 近日中国科技发展事件 据中国载人航天工程办公室消息&#xff0c;北京时间2023年5月30日6时42分&#xff0c;神舟十六号载人飞行任务航天员乘组出征仪式在酒泉卫星发射中心问天阁圆梦园广场举行。6时44分&#xff0c;中国载人航天工程…