某些應用程序需要對文件或者目錄進行監控,來偵測其是否發生了某些事件。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就阻塞。