首页 > 解决方案 > QFileSystemWatcher 文件更改信号仅发出少数文件更新的信号

问题描述

我正在使用 QFileSystemWatcher 来控制日志文件的更改。为了创建和更新日志文件,我使用了 boost 库。

当我在一个方法中记录几条消息时,文件更改信号只发出一个(对于最后一条消息),但我看到每次添加日志消息后文件都会更新。

所以,QFileSystemWatcher 的代码是

    std::string fn = "app.log";
    logging::init_log(fn);
    QFileSystemWatcher* watcher = new QFileSystemWatcher();
    auto success = QObject::connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(handleFileChanged(QString)));
    Q_ASSERT(success);
    watcher->addPath(QString::fromStdString(fn));

添加日志消息

void a(){
    /* some code */
    logging::write_log("test error", logging::kError);
    logging::write_log("test info", logging::kInfo);
}

QFileSystemWatcher 只为 Info 级别的消息发出信号。在文件管理器中,我看到每次调用后文件都会更新(测试错误、测试信息)。在日志文件初始化中,我使用

    sink->locked_backend()->auto_flush(true);

所以文件会立即更新。

我怎样才能解决这个问题?或者也许还有另一种方法来处理日志文件更新以在 GUI 中显示消息。

标签: linuxqt5boost-logqfilesystemwatcher

解决方案


类似的文件系统事件通知通常会合并为一个,除非它们被阅读器使用。例如,如果写入器向文件写入 10 个字节,则监视该文件是否写入的线程通常会看到一个事件而不是 10 个。这inotify在 Linux 的描述说明中明确概述,可能由QFileSystemWatcher.

这对于文件系统监视软件的任何正确实现都无关紧要。该通知仅允许监视器注意到发生了某些事件(例如发生了写入),并且由软件来发现有关事件的更多详细信息(例如,写入的数据量和写入位置)。

如果您的目标只是显示写入的日志,您应该能够从当前读取位置读取文件内容到文件末尾。该读取操作可能会返回一条或多条日志记录。如果 C++ 标准库以某种方式实现(例如何时auto_flush禁用,并且流缓冲区在发出之前用部分日志记录内容填充内部缓冲区write),它也可以返回不完整的日志记录。监控软件应该解析读取的内容以分离日志记录并检测不完整的日志记录(例如,用换行符分割数据)。


推荐阅读