11

我正在尝试在 C 中运行 inotify 的示例,但它不起作用。我想监视对文件的修改(文件是 tmp.cfg),但它不起作用..我不知道我是否正确运行它,因为我了解如何监视目录,但不是单个文件示例如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv )
{
  int length, i = 0;
  int fd;
  int wd;
  char buffer[BUF_LEN];

  fd = inotify_init();

  if ( fd < 0 ) {
    perror( "inotify_init" );
  }

  wd = inotify_add_watch( fd, "/home/name/tmp.cfg",
                         IN_MODIFY | IN_CREATE | IN_DELETE );
  length = read( fd, buffer, BUF_LEN );

  if ( length < 0 ) {
    perror( "read" );
  }

  while ( i < length ) {
    struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
      if ( event->mask & IN_CREATE ) {
          printf( "The file %s was created.\n", event->name );
      }
      else if ( event->mask & IN_DELETE ) {
          printf( "The file %s was deleted.\n", event->name );
      }
      else if ( event->mask & IN_MODIFY ) {
          printf( "The file %s was modified.\n", event->name );
      }
    i += EVENT_SIZE + event->len;
  }

  ( void ) inotify_rm_watch( fd, wd );
  ( void ) close( fd );

  return 0;
}

一旦我运行它,如果我在文件上写一些东西然后保存它,什么都不会发生。我试过调试它..问题似乎是 if ( event->mask & IN_MODIFY ),因为它没有将其识别为修改

4

4 回答 4

7

你有2个问题。首先,据我所知,inotify 并不能真正处理文件——它需要目录名才能观看。

其次,你错过了if (event->len) {while 循环。

此代码适用于我在当前目录中创建、删除和修改文件:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>

#define EVENT_SIZE  (sizeof(struct inotify_event))
#define BUF_LEN     (1024 * (EVENT_SIZE + 16))

int main(int argc, char **argv) {
    int length, i = 0;
    int fd;
    int wd;
    char buffer[BUF_LEN];

    fd = inotify_init();

    if (fd < 0) {
        perror("inotify_init");
    }

    wd = inotify_add_watch(fd, ".",
        IN_MODIFY | IN_CREATE | IN_DELETE);
    length = read(fd, buffer, BUF_LEN);

    if (length < 0) {
        perror("read");
    }

    while (i < length) {
        struct inotify_event *event =
            (struct inotify_event *) &buffer[i];
        if (event->len) {
            if (event->mask & IN_CREATE) {
                printf("The file %s was created.\n", event->name);
            } else if (event->mask & IN_DELETE) {
                printf("The file %s was deleted.\n", event->name);
            } else if (event->mask & IN_MODIFY) {
                printf("The file %s was modified.\n", event->name);
            }
        }
        i += EVENT_SIZE + event->len;
    }

    (void) inotify_rm_watch(fd, wd);
    (void) close(fd);

    return 0;
}
于 2012-11-13T06:08:30.130 回答
2

它不适用于单个文件,因为当我们使用编辑器修改文件时,编辑器会打开文件的副本,当我们从文本编辑器保存编辑后的版本时,现有文件被删除,新文件修改后创建了相同的名称。

删除旧文件后,在该文件上创建的监视程序将失效并自动删除。

如果您监视父目录,您可以看到旧文件被新文件替换。

有两种方法可以解决它,监视父目录并在对您要观看的特定内容进行修改时打印消息。

否则,每当进行修改时,都会在文件上创建一个新的监视。当旧文件被删除时,会触发 IN_DELETE_SELF 事件。

event->name 仅当您监视目录时才会为非空,因为它将包含在监视目录中发生事件的文件的名称。

于 2018-05-28T06:07:13.053 回答
1

我认为您没有使用您的用户名,这是您的主目录,并且您没有检查inotify_add_watch可能失败的返回:

"/home/name/tmp.cfg"

编辑:好的第二个问题,你不应该打印name,因为

name 字段仅在为监视目录中的文件返回事件时出现;

Edit2:第三个问题,在运行程序之前文件必须存在,因为你在文件上添加了一个监视,我建议你检查错误从inotify_add_watch

于 2012-11-12T20:53:38.807 回答
1

在观看文件时,如果文件被编辑器操作,您可能会对其进行编辑并创建更改,那么它可能会执行一些操作,导致您要求观看的原始文件被删除。因此,如果您只观看一个文件,通知将停止。

于 2014-02-11T03:57:00.567 回答