开发者

C/C++ Qt监控文件状态变化方式

开发者 https://www.devze.com 2025-10-22 10:43 出处:网络 作者: 王瑞MVP
目录C++ Qt监控文件状态变化定义头文件 filesystem.h实现头文件 filesystem.cpp主程序main.cpp代码中总结C++ Qt监控文件状态变化
目录
  • C++ Qt监控文件状态变化
    • 定义头文件 filesystem.h
    • 实现头文件 filesystem.cpp
    • 主程序main.cpp代码中
  • 总结

    C++ Qt监控文件状态变化

    QFileSystemWatcher 是 Qt 框架中的一个类,用于监视文件和目录的变化。

    它提供了一种机制,可以在文件系统中的特定文件或目录发生变化时通知应用程序。

    以下是 QFileSystemWatcher 的主要特性和用法:

    • 文件和目录监视: QFileSystemWatcher 可以监视一个或多个文件和目录,以便在它们发生变化时接收通知。
    • 变化类型: 支持的变化类型包括文件或目录的创建、修改、删除等。
    • 异步通知: 当被监视的文件或目录发生变化时,QFileSystemWatcher 会发出相应的信号,例如 fileChangeddirectoryChanged 信号。
    • 跨平台支持: 可在不同平台上运行,包括 Windows、linux、和 MACOS 等。
    • 简单易用: 使用方便,只需连接相应的信号槽即可处理文件系统变化的通知。

    在示例中,QFileSystemWatcher 被用于监视文件和目录的变化。

    当文件内容被修改或目录中的文件被删除时,相应的信号槽会被触发,从而执行相应的操作。

    定义头文件 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);  // 目录更新时调用,path是监控的路径
        void fileUpdated(const QString &path);   // 文件被修改时调用,path是监控的路径
    
    private:
        explicit FileSystemWatcher(QObject *parent = 0);
    
    private:
        statijsc FileSystemWatcher *m_pInstance; // 单例
        QFileSystemWatcher *m_pSystemWatcher;  // QFileSystemWatcher变量
        QMap<QString, QStringList> m_currentContentsMap; // 当前每个监控的内容目录列表
    
    };
    #endif // FILESYSTEM_H

    实现头文件 filesystem.cpp

    #include <QDir>
    #include <QFileInfo>
    #include <qDebug>
    #include "filesystem.h"
    
    FileSystemWatcher* FileSystemWatcher::m_pInstance = NULL;
    FileSystemWatcher::FileSystemWatcher(QObject *parent)
        : QObject(parent)
    {
    
    }
    
    // 监控文件或目录
    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信号到相应的槽
            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 FileSystemWatcher::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 www.devze.com- currentDirSet;
        QStringList newFile = newFiles.toList();
    
        // 文件已被移除
        QSet<QString> deletedFiles = currwww.devze.comentDirSet - 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
    www.devze.com        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 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代码中

    直接调用

    FileSystemWatcher::addWatchPath("c://test");

    监控C盘下的test目录,当有文件发生变化时自动触发。

    #include <QCoreApplication>
    #include "filesystem.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        FileSystemWatcher::addWatchPath("c://test");
    
        return编程 a.exec();
    }

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号