某些应用程序需要对文件或者目录进行监控,来侦测其是否发生了某些事件。Linux很贴心的为我们提供了inotify API,也是Linux的专有。
inotify API
在使用之前一定要有一个inotify实例,int inotify_init(void);返回一个inotify实例的描述符。
添加监控描述符,int inotify_add_watch(int fd,const char *pathname,unit32_t mask);参数解释:fd就是init返回的描述符,pathname就是你要监控的文件或者目录的路径名,mask这个是用来表示你要监控的事件类型。
删除监控描述符,int inotify_rm_watch(int fd,uint32_t wd);参数解释:fd还是你要操作的描述符,wd是你要删除监控描述符号。
inotify事件
inotify事件实现原理
原理肯定需要数据结构来支撑了,先来一个inotify的通知事件数据结构:
struct inotify_event{ int wd;监控描述符 uint32_t mask;发生的事件 uint32_t cookie;这个专为文件重命名而生,源文件所在监控会产生一个IN_MOVED_FROM事件,重命名后文件所在监控会产生一个IN_MOVED_TO事件(如果在同一个监控下重命名,会对这个监控项产生这两个事件)。这两个事件的cookie值相等,方便应用程序将他俩事件关联起来。多么巧妙而朴实的设计啊。 uint32_t len;name字符串的长度 char name[];表示受监控目录下发生事件的文件名,以\0结尾。\0结尾后可能有填充字符。 }
这个地方我要吐槽下这个char name[];C不支持但是C++支持。在算结构体大小的时候,他的大小为0。但是我们为这个char name[]开辟空间的时候,可以通过直接添加长度。举例说明一下,我要用这个结构体去填充我的一个buffer,char buffer[LEN];我们可以这么定义LEN:#define LEN 10*(sizeof(struct inotify_event)+10),这样我们的buffer的数据空间就可以用下图来表示。
调用read就能从内核读取所发生的事件,如果事件队列为空,read就阻塞。
来源:https://www.cnblogs.com/sylz/p/6051097.html