
第三代软件开发-文件监视器
文章目录
关键字:
Qt
、
Qml
、
关键字3
、
关键字4
、
关键字5
项目介绍
重要说明☝
☀该专栏在第三代软开发更新完将涨价
文件监视器
如果你看过我前面【第三代软件开发-U盘监测】的话,在哪里会发现有一个文件监视器,指的就是这个模块
实现原理
如下图所示,其实就是在Qt的文件监视器基础上做了细分,支持之别是文件增加、减少和重命名。
关于 QFileSystemWatcher
实现代码
代码基本不怎么复杂,直接上代码吧
#include <QObject>
#include <QDebug>
#include <QMap>
#include <QFileSystemWatcher>
#include <QFileInfo>
#include <QDir>
class XXXX : public QObject
{
Q_OBJECT
public:
explicit XXXX(QObject *parent = nullptr);
void addWatchPath(QString path);
void removeWatchPath(QString path);
void getInitFile(QString path);
public slots:
void slotDirectoryUpdated(const QString // 目录更新时调用,path是监控的路径
void slotFileUpdated(const QString // 文件被修改时调用,path是监控的路径
signals:
// 添加新文件/目录至Dir
void signalAddFile(QString strFolder, QString strFile);
// 从Dir中删除文件/目录
void signalDeleteFile(QString strFolder, QString strFile);
// 文件/目录重命名
void signalRenamedFile(QString strFolder, QString strNewName, QString strOldName);
private:
// static XXXX *m_pInstance; // 单例
QFileSystemWatcher* m_pSystemWatcher = nullptr; // QFileSystemWatcher变量
QMap<QString, QStringList> m_currentContentsMap; // 当前每个监控的内容目录列表
};
#endif // XXXX_H
#include "XXXX.h"
/**
* @brief XXXX::XXXX
* @param parent
* 构造函数
*/
XXXX::XXXX(QObject *parent) : QObject(parent)
{
m_pSystemWatcher = new QFileSystemWatcher;
// 连接QFileSystemWatcher的directoryChanged和fileChanged信号到相应的槽
connect(m_pSystemWatcher,&QFileSystemWatcher::directoryChanged,
this,&XXXX::slotDirectoryUpdated);
connect(m_pSystemWatcher,&QFileSystemWatcher::fileChanged,
this,&XXXX::slotFileUpdated);
}
/**
* @brief XXXX::addWatchPath
* @param path
* 添加监控路径
*/
void XXXX::addWatchPath(QString path)
{
// 添加监控路径
m_pSystemWatcher->addPath(path);
// 如果添加路径是一个目录,保存当前内容列表
QFileInfo file(path);
if (file.isDir())
{
QDir dirw(path);
m_currentContentsMap[path] = dirw.entryList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
}
}
/**
* @brief XXXX::removeWatchPath
* @param path
* 移除监控路径
*/
void XXXX::removeWatchPath(QString path)
{
m_pSystemWatcher->removePath(path);
}
/**
* @brief XXXX::getInitFile
* @param path
* 获取初始文件
*/
void XXXX::getInitFile(QString path)
{
}
/**
* @brief XXXX::slotDirectoryUpdated
* @param path
* 目录更新槽函数
*/
void XXXX::slotDirectoryUpdated(const QString &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))
{
emit signalRenamedFile(path,newFile.first(),deleteFile.first());
}
}
else
{
// 添加新文件/目录至Dir
if (!newFile.isEmpty())
{
foreach (QString file, newFile)
{
qDebug() << "新增文件路径:" << file;
// 处理操作每个新文件....
emit signalAddFile(path,file);
}
}
// 从Dir中删除文件/目录
if (!deleteFile.isEmpty())
{
foreach(QString file, deleteFile)
{
// 处理操作每个被删除的文件....
emit signalDeleteFile(path,file);
}
}
}
}
/**
* @brief XXXX::slotFileUpdated
* @param path
* 文件更新
*/
void XXXX::slotFileUpdated(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);
}
真的很简单,不用解释过多吧。这个不是我的原创,是我们公司小伙伴写的,我的智商能理解,我就认为你也理解,因为我和我小伙伴说要把我当成傻逼才行。
