C/C++ Qt監(jiān)控文件狀態(tài)變化方式
C++ Qt監(jiān)控文件狀態(tài)變化
QFileSystemWatcher 是 Qt 框架中的一個(gè)類,用于監(jiān)視文件和目錄的變化。
它提供了一種機(jī)制,可以在文件系統(tǒng)中的特定文件或目錄發(fā)生變化時(shí)通知應(yīng)用程序。
以下是 QFileSystemWatcher 的主要特性和用法:
- 文件和目錄監(jiān)視:
QFileSystemWatcher可以監(jiān)視一個(gè)或多個(gè)文件和目錄,以便在它們發(fā)生變化時(shí)接收通知。 - 變化類型: 支持的變化類型包括文件或目錄的創(chuàng)建、修改、刪除等。
- 異步通知: 當(dāng)被監(jiān)視的文件或目錄發(fā)生變化時(shí),
QFileSystemWatcher會(huì)發(fā)出相應(yīng)的信號(hào),例如fileChanged或directoryChanged信號(hào)。 - 跨平臺(tái)支持: 可在不同平臺(tái)上運(yùn)行,包括 Windows、Linux、和 macOS 等。
- 簡單易用: 使用方便,只需連接相應(yīng)的信號(hào)槽即可處理文件系統(tǒng)變化的通知。
在示例中,QFileSystemWatcher 被用于監(jiān)視文件和目錄的變化。
當(dāng)文件內(nèi)容被修改或目錄中的文件被刪除時(shí),相應(yīng)的信號(hào)槽會(huì)被觸發(fā),從而執(zhí)行相應(yīng)的操作。
定義頭文件 filesystem.h
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#include <QObject>
#include <QMap>
#include <QFileSystemWatcher>
class FileSystemWatcher : public QObject
{
Q_OBJECT
public:
static void addWatchPath(QString path);
public slots:
void directoryUpdated(const QString &path); // 目錄更新時(shí)調(diào)用,path是監(jiān)控的路徑
void fileUpdated(const QString &path); // 文件被修改時(shí)調(diào)用,path是監(jiān)控的路徑
private:
explicit FileSystemWatcher(QObject *parent = 0);
private:
static FileSystemWatcher *m_pInstance; // 單例
QFileSystemWatcher *m_pSystemWatcher; // QFileSystemWatcher變量
QMap<QString, QStringList> m_currentContentsMap; // 當(dāng)前每個(gè)監(jiān)控的內(nèi)容目錄列表
};
#endif // FILESYSTEM_H實(shí)現(xiàn)頭文件 filesystem.cpp
#include <QDir>
#include <QFileInfo>
#include <qDebug>
#include "filesystem.h"
FileSystemWatcher* FileSystemWatcher::m_pInstance = NULL;
FileSystemWatcher::FileSystemWatcher(QObject *parent)
: QObject(parent)
{
}
// 監(jiān)控文件或目錄
void FileSystemWatcher::addWatchPath(QString path)
{
qDebug() << QString("Add to watch: %1").arg(path);
if (m_pInstance == NULL)
{
m_pInstance = new FileSystemWatcher();
m_pInstance->m_pSystemWatcher = new QFileSystemWatcher();
// 連接QFileSystemWatcher的directoryChanged和fileChanged信號(hào)到相應(yīng)的槽
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)));
}
// 添加監(jiān)控路徑
m_pInstance->m_pSystemWatcher->addPath(path);
// 如果添加路徑是一個(gè)目錄,保存當(dāng)前內(nèi)容列表
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);
}
}
// 只要任何監(jiān)控的目錄更新(添加、刪除、重命名),就會(huì)調(diào)用。
void FileSystemWatcher::directoryUpdated(const QString &path)
{
qDebug() << QString("Directory updated: %1").arg(path);
// 比較最新的內(nèi)容和保存的內(nèi)容找出區(qū)別(變化)
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();
// 更新當(dāng)前設(shè)置
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)
{
// 處理操作每個(gè)新文件....
}
}
// 從Dir中刪除文件/目錄
if (!deleteFile.isEmpty())
{
qDebug() << "Files/Dirs deleted: " << deleteFile;
foreach(QString file, deleteFile)
{
// 處理操作每個(gè)被刪除的文件....
}
}
}
}
// 文件修改時(shí)調(diào)用
void FileSystemWatcher::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代碼中
直接調(diào)用
FileSystemWatcher::addWatchPath("c://test");監(jiān)控C盤下的test目錄,當(dāng)有文件發(fā)生變化時(shí)自動(dòng)觸發(fā)。
#include <QCoreApplication>
#include "filesystem.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
FileSystemWatcher::addWatchPath("c://test");
return a.exec();
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
c++實(shí)現(xiàn)跳躍表(Skip List)的方法示例
跳表(skiplist)是一個(gè)非常優(yōu)秀的數(shù)據(jù)結(jié)構(gòu),實(shí)現(xiàn)簡單,插入、刪除、查找的復(fù)雜度均為O(logN),下面這篇文章主要介紹了c++實(shí)現(xiàn)跳躍表(Skip List)的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09
C語言中計(jì)算函數(shù)執(zhí)行時(shí)間的三種方式
本文主要介紹了C語言中計(jì)算函數(shù)執(zhí)行時(shí)間的三種方式,主要包括clock(),timeb和time,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
詳解C語言中sizeof如何在自定義函數(shù)中正常工作
在main函數(shù)中,sizeof是可以正常工作的,但是在自定義函數(shù)中就不可以了。所以本文將為大家詳細(xì)講解一下如何解決這一問題,感興趣的可以了解一下2022-05-05

