C语言中的inotify文件
Posted
技术标签:
【中文标题】C语言中的inotify文件【英文标题】:inotify file in C 【发布时间】:2012-11-12 20:36:57 【问题描述】:我正在尝试在 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 ),因为它没有将其识别为修改
【问题讨论】:
只是好奇:为什么要将 inotify_rm_watch() 和 close() 的返回值强制转换为 void? 【参考方案1】:您有 2 个问题。首先,据我所知,inotify 并不能真正处理文件——它需要目录名才能查看。
其次,你在 while 循环中错过了if (event->len)
。
此代码适用于我在当前目录中创建、删除和修改文件:
#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;
【讨论】:
你可能是对的。但是,如果我使用文件名,更改通知似乎对我不起作用name
也不应该被打印出来,因为只有当监视目录中的文件发生变化时才会出现。
啊,我明白了。但它只有在文件已经存在时才有效。似乎监视目录和比较文件名更健壮(但如果其他文件更改可能会很慢)
是的,文件必须首先存在,因为手表已添加到文件中。
由于某种原因它不适用于文件..我不知道为什么,因为当我尝试对目录进行 inotify 时它工作正常。【参考方案2】:
它不适用于单个文件,因为当我们使用编辑器修改文件时,编辑器会打开文件的副本,当我们从文本编辑器保存编辑后的版本时,现有文件会被删除,并且修改后创建同名的新文件。
当旧文件被删除时,在该文件上创建的监视将失效并被自动删除。
如果您监视父目录,您可以看到旧文件被新文件替换。
有两种方法可以解决它,监视父目录并在对您要观看的特定内容进行修改时打印消息。
否则,每当进行修改时,都会在文件上创建一个新监视。当旧文件被删除时,会触发 IN_DELETE_SELF 事件。
event->name 仅当您监视目录时才会为非空,因为它将包含在监视目录中发生事件的文件的名称。
【讨论】:
【参考方案3】:我认为您没有使用您的 用户名,这是您的主目录,并且您没有检查可能失败的 inotify_add_watch
的返回:
"/home/name/tmp.cfg"
编辑:好的第二个问题,你不应该打印name
,因为
名称字段仅在为文件返回事件时出现 在被监视的目录中;
Edit2:第三个问题,文件必须存在才能运行程序,因为你在文件上加了watch,建议你检查inotify_add_watch
的错误
【讨论】:
我试过调试它..问题似乎是 if ( event->mask & IN_MODIFY ),因为它不将其识别为修改 @user1693049 我尝试了代码,它在这里工作,没有发现任何问题【参考方案4】:在观看文件时,如果文件被编辑器操作,您可能会对其进行编辑并创建更改,那么它可能会执行一些操作,导致您要求观看的原始文件被删除。因此,如果您只观看一个文件,通知将停止。
【讨论】:
以上是关于C语言中的inotify文件的主要内容,如果未能解决你的问题,请参考以下文章