I have a QT app that needs to know when new data is available in a specific file. So I used QFileSystemWatcher and connected the fileChanged signal to a function that will send a message in case of changes.
The probelm is that the fileChanged signal is not emitted when another application flushes this file, but only after it closes the file.
However, the QFileSystemWatcher documentation says that this signal is emitted "when the file at the specified path is modified, renamed or removed from disk".
Maybe I'm missing something; What changes are included in modified? If flushing is not included, How can I detect when new data has been written to the file?
Here is the source code:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#include <QFileSystemWatcher>
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void fileChangedEvent(const QString & path);
private:
QFileSystemWatcher * watcher;
};
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow()
{
watcher = new QFileSystemWatcher();
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(fileChangedEvent(QString)));
watcher->addPath("path to file");
}
void MainWindow::fileChangedEvent(const QString & path)
{
qDebug() << path;
}
MainWindow::~MainWindow()
{
if(watcher!=NULL)
{
delete watcher;
watcher=NULL;
}
}
This is the code of the another application which changes the file (this is a 3rd party app, so I can't change it to be synchronized with):
#include <fstream>
int main () {
std::ofstream outfile ("path to file");
for (int n=0; n<100; ++n)
{
outfile << n;
outfile.flush();
}
outfile.close();
return 0;
}
The fileChanged() signal is emitted only after std::ofstream outfile ("path to file");and outfile.close(); are called and not after outfile.flush();
That loop of write and flush is pretty fast (microseconds!?). You can not expect that the QFileSytemWatcher get's notice of all of that actions as it may well be implemented using timers .. and everything is over so fast that you are informed only unreliably about what's going on.
I just testet it and found out this assumption is correct. Consider the following code. It is writer which writes either timed or everything in a row without delay. Using a delay will give your watcher time to get notice about every single flush. But without delay it rarely reports more than two file system changes.