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 等。
- 簡(jiǎn)單易用: 使用方便,只需連接相應(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)輸入兩個(gè)數(shù)字將其按從小到大輸出的方法
這篇文章主要介紹了C語言實(shí)現(xiàn)輸入兩個(gè)數(shù)字將其按從小到大輸出的方法,本文通過代碼講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
文件編譯時(shí)出現(xiàn)multiple definition of ''xxxxxx''的具體解決方法
以下是對(duì)文件編譯時(shí)出現(xiàn)multiple definition of 'xxxxxx'的解決方法進(jìn)行了詳細(xì)的分析介紹,如也遇到此問題的朋友們可以過來參考下2013-07-07
C/C++實(shí)現(xiàn)內(nèi)存泄漏檢測(cè)詳解
這篇文章主要為大家詳細(xì)介紹了c++進(jìn)行內(nèi)存泄漏檢測(cè)的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下,希望能夠給你帶來幫助2023-02-02
Qt事件過濾實(shí)現(xiàn)點(diǎn)擊圖片的放大和縮小
這篇文章主要為大家詳細(xì)介紹了Qt事件過濾實(shí)現(xiàn)點(diǎn)擊圖片的放大和縮小,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
C語言實(shí)現(xiàn)簡(jiǎn)單的學(xué)生學(xué)籍管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡(jiǎn)單的學(xué)生學(xué)籍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
解析c中stdout與stderr容易忽視的一些細(xì)節(jié)
本篇文章是對(duì)在c語言中stdout與stderr容易忽視的一些細(xì)節(jié)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05

