44

我想inotify在 Linux 上使用该机制。我希望我的应用程序知道文件何时aaa更改。你能给我一个样本如何做到这一点吗?

4

4 回答 4

43

C inotifyAPI

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

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

read()close()系统调用也是需要的。给定由 产生的描述符inotify_init(),调用read()以等待警报。假设一个典型的文件描述符,应用程序阻塞等待事件的接收,这些事件在流中表示为数据。文件描述符上的通用 close() 产生于inotify_init()删除并释放所有活动监视以及与 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 上添加了一个监视,用于任何修改、文件创建或文件删除。

于 2010-10-31T10:56:10.983 回答
14

下面是如何使用 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 */
于 2010-11-02T18:10:56.823 回答
10

如果您只需要一个命令行应用程序,那么可以使用一个名为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.

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

于 2018-03-16T21:06:58.067 回答
2

由于最初的问题似乎提到 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;
}
于 2016-04-25T17:18:08.800 回答