Qt之QFileSystemWatcher目錄或文件變化

FileSystemWatcher.h

#ifndef FILESYSTEMWATCHER_H
#define FILESYSTEMWATCHER_H

#include <QObject>
#include <QMap>
#include <QFileSystemWatcher>

class FileSystemWatcher : public QObject
{
	Q_OBJECT

public:
	//FileSystemWatcher(QObject *parent);
	~FileSystemWatcher();

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:
	static FileSystemWatcher *m_pInstance; // 單例
	QFileSystemWatcher *m_pSystemWatcher;  // QFileSystemWatcher變量
	QMap<QString, QStringList> m_currentContentsMap; // 當前每個監控的內容目錄列表
	
};

#endif // FILESYSTEMWATCHER_H

cpp

#include "filesystemwatcher.h"
#include <QDir>
#include <QFileInfo>
#include <qDebug>

FileSystemWatcher* FileSystemWatcher::m_pInstance = NULL;

FileSystemWatcher::FileSystemWatcher(QObject *parent)
	: QObject(parent)
{

}

FileSystemWatcher::~FileSystemWatcher()
{

}

// 監控文件或目錄
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 - 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 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

#include <QtCore/QCoreApplication>
#include "filesystemwatcher.h"

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);
	FileSystemWatcher::addWatchPath("E:/Test");
	return a.exec();
}
vs2010+qt5.5.1
發佈了43 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章