我有一个QT应用,需要知道特定文件中何时有新数据。所以我使用QFileSystemWatcher
并将fileChanged
信号连接到一个函数,该函数会在发生更改时发送消息。
问题是,当另一个应用程序刷新此文件时,不会发出fileChanged
信号,但只有在它关闭文件后才会发出。
然而,QFileSystemWatcher documentation表示发出此信号"当指定路径上的文件被修改,重命名或从磁盘中移除时#34;。
也许我错过了一些东西; modified
中包含哪些更改?如果不包括刷新,如何检测何时将新数据写入文件?
以下是源代码:
的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;
}
}
这是另一个更改文件的应用程序的代码(这是第三方应用程序,因此我无法将其更改为与之同步):
#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;
}
仅在调用fileChanged()
和std::ofstream outfile ("path to file");
之后发出outfile.close();
信号,而不是在outfile.flush();
答案 0 :(得分:1)
在Windows上,当文件的时间戳发生变化时,似乎发出fileChanged
信号,这发生在文件关闭(std::ofstream::close()
)但不发生时(至少在Windows上)它是刷新的(std::ofstream::flush()
)。为了测试它,我使用以下函数在每次写入文件时(在调用std::ofstream::flush()
之后)显式更新了文件的时间戳:
#include <ctime>
#include <sys/stat.h>
#ifdef _WIN32
#include <sys/utime.h>
#else
#include <utime.h>
#endif
bool UpdateFileTimestamp(std::string fileName) {
struct stat fstat;
struct utimbuf new_time;
if (0 != stat(fileName.c_str(), &fstat))
return false;
new_time.actime = fstat.st_atime;
new_time.modtime = time(NULL);
if (0 != utime(fileName.c_str(), &new_time))
return false;
return true;
}
它有效。 fileChanged
信号按预期发出。
答案 1 :(得分:0)
写入和刷新循环非常快(微秒!?)。您不能指望QFileSytemWatcher会注意到所有这些操作,因为它可能是使用计时器实现的......而且一切都过快,以至于您只能不明白地了解正在发生的事情。
我只是测试它并发现这个假设是正确的。请考虑以下代码。它是写作者,可以毫不拖延地连续写入时间或一切。使用延迟将使您的观察者有时间了解每次冲洗。但是没有延迟,它很少报告两个以上的文件系统更改。
#include "mainwindow.h"
#include <QDebug>
#include <QTimer>
MainWindow::MainWindow()
: m_count(10), m_file("./file")
{
m_file.open(QFile::Truncate | QFile::ReadWrite);
// CHECK THIS:
QTimer * t = new QTimer(this);
connect(t,SIGNAL(timeout()), SLOT(writeChunk()));
t->start(100);
// AGAINST THIS:
//for(int i = 0; i < 10; i++) writeChunk();
}
void MainWindow::writeChunk()
{
qDebug() << "wrinteChunk()";
m_file.write("Hallo Spencer!");
m_file.flush();
if( ! --m_count ) {
m_file.close();
qDebug() << "Wrote 10 chunks";
exit(0);
}
}
MainWindow::~MainWindow()
{
}