使用inotify的正确方法是什么?

问题描述 投票:22回答:4

我想在Linux上使用inotify机制。我希望我的应用程序知道文件aaa何时被更改。你能告诉我一些如何做到的样品吗?

linux inotify
4个回答
28
投票

inotify C API

inotify提供三个系统调用来构建各种文件系统监视器:

  • inotify_init()在内核中创建inotify子系统的实例,并在成功时返回文件描述符,并在失败时返回-1。与其他系统调用一样,如果inotify_init()失败,请检查errno以进行诊断。
  • 顾名思义,inotify_add_watch()增加了一块手表。每个监视必须提供路径名和相关事件列表,其中每个事件由常量指定,例如IN_MODIFY。要监视多个事件,只需在每个事件之间使用C-中的逻辑或管道(|)运算符。如果inotify_add_watch()成功,则呼叫将返回已注册手表的唯一标识符;否则,它返回-1。使用标识符可以更改或删除关联的监视。
  • inotify_rm_watch()删除了一块手表。

还需要read()close()系统调用。鉴于inotify_init()产生的描述符,请调用read()等待警报。假设一个典型的文件描述符,应用程序阻止接收事件,这些事件表示为流中的数据。从inotify_init()产生的文件描述符上的公共close()删除并释放所有活动监视以及与inotify实例关联的所有内存。 (典型的引用计数警告也适用于此。与实例关联的所有文件描述符必须在手表消耗的内存和inotify被释放之前关闭。)

#include "inotify.h"  
#include "inotify-syscalls.h"  
int wd;   
wd = inotify_add_watch (fd,   
            "/home/rlove/Desktop", IN_MODIFY | IN_CREATE | IN_DELETE);
if (wd < 0)
      perror ("inotify_add_watch");

此示例在目录/ home / rlove / Desktop上添加一个监视,用于任何修改,文件创建或文件删除。


12
投票

下面是一个如何使用inotify观看“aaa”的片段。请注意,我没有测试过这个,我甚至没有编译过它!您需要为其添加错误检查。

您也可以在inotfd上使用poll / select,而不是使用阻塞读取。

const char *filename = "aaa";
int inotfd = inotify_init();

int watch_desc = inotify_add_watch(inotfd, filename, IN_MODIFY);

size_t bufsiz = sizeof(struct inotify_event) + PATH_MAX + 1;
struct inotify_event* event = malloc(bufsiz);

/* wait for an event to occur */
read(inotfd, event, bufsiz);

/* process event struct here */

5
投票

如果你需要的只是一个命令行应用程序,有一个名为inotifywait使用inotify监视文件

从终端1

# touch cheese
# while inotifywait -e modify cheese; do 
>   echo someone touched my cheese
> done

从终端2

echo lol >> cheese

这是终端1上看到的内容

Setting up watches.
Watches established.
cheese MODIFY 
someone touched my cheese
Setting up watches.
Watches established.

更新:谨慎使用并查看评论。


0
投票

由于最初的问题似乎提到Qt作为标签,如此处的几条评论所述,搜索引擎可能会引导您到这里。

如果有人想知道如何使用Qt,请参阅http://doc.qt.io/qt-5/qfilesystemwatcher.html获取Qt版本。在Linux上,它使用Inotify的一个子集,如果可用,请参阅Qt页面上的说明以获取详细信息。

基本上所需的代码如下所示:

在mainwindow.h中添加:

QFileSystemWatcher * watcher;
private slots:
    void directoryChanged(const QString & path);
    void fileChanged(const QString & path);

并为mainwindow.cpp:

#include <QFileInfo>
#include <QFileSystemWatcher>

watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(const QString &)), this, SLOT(fileChanged(const QString &)));
connect(watcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
watcher->addPath("/tmp/"); // watch directory
watcher->addPath("/tmp/a.file");  // watch file

还要在mainwindow.cpp中添加插槽,如果注意到文件/目录更改,则调用这些插槽:

void MainWindow::directoryChanged(const QString & path) {
     qDebug() << path;
}
void MainWindow::fileChanged(const QString & path) {
     qDebug() << path;
}
© www.soinside.com 2019 - 2024. All rights reserved.