[Development] QFileSystemWatcher and Recursive Monitoring

d3fault d3faultdotxbe at gmail.com
Fri Jul 27 08:20:09 CEST 2012


On Thu, Jul 26, 2012 at 9:55 AM, logic.cpp <logic.cpp at gmail.com> wrote:
> So how about something like this (others have suggested something along these lines):
>
> In order to work recursively,

Recursive isn't the same problem. Recursive is easy. The only problem
with doing recursive before was that 256 fd limit on Mac... which I
think we should get around by using FSEvents.


The rest of your  post was kind of confusing, but I came up with a
design where everyone wins. It's just a high level public API design,
but you should be able to easily figure out the internals from it (let
me know if you can't).

It's:
1) Cross platform without requiring the user to write custom code
2) Customizable/optimizable for the apps that need/want it
3) Efficient on platforms that support fine grained notifications,
inefficient (unless you do (2) above) on platforms without


Here you go, I used overly verbose wording to make it as clear as
possible. Also, I'm not sure how interfaces are supposed to be named
within Qt so I just guessed. And note the pure virtual public slot in
the interface... it should help explain.



class QFileSystemWatcher : public QObject
{
	Q_OBJECT
public:
	QFileSystemWatcher(QObject *parent = 0);
	QFileSystemWatcher(IQFileSystemWatcherSpecialCoarseToFineGrainedNotificationsFigureOuter
*userCustomSnapshotComparisonCode, QObject *parent = 0);

	void addPath(const QString &path, bool recursive = false);
	void addPaths(const QStringList &paths, bool recursive = false);
	QStringList directories() const;
	QStringList files() const;
	void removePath(const QString &path, bool recursivelyRemove = false);
	void removePaths(const QStringList &paths, bool recursivelyRemove = false);
signals:
	void directoryChanged(const QString &dir);
	void fileChanged(const QString &file);
};

class IQFileSystemWatcherSpecialCoarseToFineGrainedNotificationsFigureOuter
: public QObject
{
	Q_OBJECT
public slots:
	virtual void dirChangedSoFigureOutFileChangesAndEmitThem(const QString &dir)=0;
signals:
	void manuallyDetectedFileChanged(const QString &file);
};

class QFileSystemWatcherDefaultSpecialCoarseToFineGrainedNotificationsFigureOuter
: public IQFileSystemWatcherSpecialCoarseToFineGrainedNotificationsFigureOuter
{
	Q_OBJECT
public slots:
	void dirChangedSoFigureOutFileChangesAndEmitThem(const QString &dir)
	{
		//here is the default implementation using the most common method
(snapshot comparison of file properties) for detecting fine grained
notifications

		//after we detect a file in the dir has changed, we simply do:
		emit manuallyDetectedFileChanged(filename);
	}
};


using it:
//if you want cross-platform support and don't care that some
platforms will be very slow
QFileSystemWatcher *fsw = new QFileSystemWatcher();

//if you have a special app and want to do some optimized detection
(but this is only applicable to platforms that don't already provide
fine-grained. in those cases the interface is simply ignored)
IQFileSystemWatcherSpecialCoarseToFineGrainedNotificationsFigureOuter
*myOptimizedDetector = new MyOptimizedDetector();
QFileSystemWatcher *fsw = new QFileSystemWatcher(myOptimizedDetector);


d3fault



More information about the Development mailing list