首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >QFileSystemWatcher:检测文件是否已刷新

QFileSystemWatcher:检测文件是否已刷新
EN

Stack Overflow用户
提问于 2015-12-14 12:50:26
回答 2查看 1.1K关注 0票数 3

我有一个QT应用程序,需要知道什么时候新的数据在一个特定的文件中可用。因此,我使用了QFileSystemWatcher,并将fileChanged信号连接到一个函数,该函数将在发生更改时发送消息。

问题是,当另一个应用程序刷新该文件时,fileChanged信号不会发出,而是只在它关闭该文件之后发出。

但是,QFileSystemWatcher文档表示,“当指定路径上的文件被修改、重命名或从磁盘中删除”时,就会发出此信号。也许我遗漏了什么;modified中包含了哪些更改?如果不包括刷新,如何检测新数据何时已写入文件?

以下是源代码:

main.cpp

代码语言:javascript
复制
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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;
    }
}

这是另一个应用程序的代码,它会更改文件(这是一个第三方应用程序,所以我不能将它更改为与其同步):

代码语言:javascript
复制
#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();之后发出。

EN

回答 2

Stack Overflow用户

发布于 2016-10-28 08:21:52

在Windows上,fileChanged信号似乎是在文件的时间戳更改时发出的,而当文件被关闭(std::ofstream::close())时发出,而在刷新(std::ofstream::flush())时则不发出(至少在std::ofstream::flush()上)。为了测试它,我每次(在调用std::ofstream::flush()之后)使用以下函数显式更新文件的时间戳:

代码语言:javascript
复制
#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
EN

Stack Overflow用户

发布于 2015-12-14 13:16:21

写和刷新的循环非常快(微秒!?)。您不能期望QFileSytemWatcher得到所有这些操作的通知,因为它很可能是使用计时器实现的。一切都结束得如此之快,以至于你只被不可靠地告知了发生了什么。

我只是测试了一下,发现这个假设是正确的。请考虑以下代码。不是时间上的,就是每一件事都是由作家来写的。使用延迟会让你的观察者有时间去了解每一次冲水的情况。但是,它很少报告超过两个文件系统的更改。

代码语言:javascript
复制
#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()
{

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34267516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档