现在的位置: 首页 > 综合 > 正文

如何使用inotify编写目录监控程序

2013年12月11日 ⁄ 综合 ⁄ 共 2424字 ⁄ 字号 评论关闭

转自:http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201011209823241/

inotify是什么?用它能干些什么?

通俗点说它是一个内核用于通知用户空间程序文件系统变化的系统,并且它是powerful yet simple的。

inotify的用户接口原型主要有以下3个:

#include

初始化:int inotify_init(void);

int fd = inotify_init();

添加监视对象:int inotify_add_watch(int fd, const char *path, uint32_t mask);

int wd = inotify_add_watch(fd,path,mask);

fd是inotify_init()的返回值。

const char *path是要监控的文件(目录)的路径。

uint32_t mask是:

IN_ACCESS,即文件被访问

IN_MODIFY,文件被 write

IN_ATTRIB,文件属性被修改,如 chmod、chown、touch 等

IN_CLOSE_WRITE,可写文件被 close

IN_CLOSE_NOWRITE,不可写文件被 close

IN_OPEN,文件被 open

IN_MOVED_FROM,文件被移走,如 mv

IN_MOVED_TO,文件被移来,如 mv、cp

IN_CREATE,创建新文件

IN_DELETE,文件被删除,如 rm

IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己

IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己

IN_UNMOUNT,宿主文件系统被 umount

IN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)

IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)

mask 是事件掩码, 在头文件 linux/inotify.h 中定义了每一位代表的事件

还有非常多的事件可以使用。使用man inotify可以查看所有可以监听的事件。

mask是上面这些事件的或。例如IN_ACCESS|IN_MODIFY。

返回值:wd表示对那个文件进行监控。

删除监视对象:int inotify_rm_watch(int fd, uint32_t wd);

参数fd是inotify_init的返回值。

wd是inotify_add_watch的返回值。

inotify_rm_watch删除对wd所指向的文件的监控。

读取监控发生的事件:

size_t len = read(fd, buf, BUF_LEN);

读取事件数据,buf应是一个指向inotify_event结构数组的指针。不过要注意的是inotify_event的name成员长度是可变的,这个问题后面再解释。

注意:其中buf是一个指向struct inotify_event数组的指针。

由于struct inotify_event长度是可变的,因此在读取inotify_event数组内容的时候需要动态计算一下时间数据的偏移量。index += sizeof(struct inotify_event)+event->len,len即name成员的长度。

其实还是没有讲的很清楚,不过看了下面的例子,一定非常清楚:

#include
#include
#include
#include
#include

static void _inotify_event_handler(struct inotify_event *event) //从buf中取出一个事件。

{

printf("event->mask: 0x%08x/n", event->mask);

printf("event->name: %s/n", event->name);

}

int main(int argc, char **argv)

{

if (argc != 2) {

printf("Usage: %s /n", argv[0]);

return -1;

}

unsigned char buf[1024] = {0};

struct inotify_event *event = NULL;

int fd = inotify_init(); //初始化

int wd = inotify_add_watch(fd, argv[1], IN_ALL_EVENTS); //监控指定文件的ALL_EVENTS。

for (;;)

{

fd_set fds;

FD_ZERO(&fds);

FD_SET(fd, &fds);

if (select(fd + 1, &fds, NULL, NULL, NULL) > 0) //监控fd的事件。当有事件发生时,返回值>0

{

int len, index = 0;

while (((len = read(fd, &buf, sizeof(buf)))
while (index

{

event = (struct inotify_event *)(buf + index);

_inotify_event_handler(event); //获取事件。

index += sizeof(struct inotify_event) + event->len; //移动index指向下一个事件。

}

}

}

inotify_rm_watch(fd, wd); //删除对指定文件的监控。

return 0;

}

参考:

:inotify监控linux系统下的目录变化 http://www.javaeye.com/topic/747414

inotify -- Linux 2.6 内核中的文件系统变化通知机制 http://www.ibm.com/developerworks/cn/linux/l-inotifynew/index.html

CentOS 5.4 rsync+inotify配置触发式(实时)文件远程同步 http://www.jb51.net/os/RedHat/34547.html

Powered by Zoundry Raven

抱歉!评论已关闭.