有時候我們需要檢測某個目錄下文件或者子目錄的改動狀況,如添加、刪除、以及更新等,Linux系統上提供了inotify來完成這個功能。inotify是在版本2.6.13的內核中首次出現,現在的發行本應該都包含這個系統調用了。
下面的描述中的文件如無特別說明包括文件以及目錄
使用inotify的第一步就是調用inotify_init()創建一個inotify實例,該函數返回一個文件描述符。這個文件描述符關聯了一個inotify事件隊列,通過read讀取該文件描述符,就能獲取底層的inotify事件。
1
|
int
inotify_fd = inotify_init();
|
還有另外一個系統調用inotify_init1(int flag),該函數提供了一個參數可用於設置文件描述符屬性
1
|
int
inotify_fd = inotify_init1(flag);
|
其效果與如下代碼相同
1
2
|
int
inotify_fd = inotify_init();
fcntl(inotify_fd, F_SETFL, flags)
|
一旦成功創建了inotify實例,獲得了相應的文件描述符,下一步就是告訴內核需要關注的文件以及關注的事件類型。這一步是通過函數inotify_add_watch()實現的。
1
|
int
wd = inotify_add_watch(instance_fd, file_name, event_mask)
|
上面的調用中,file_name就是需要關注的文件,而event_mask是關注的事件類型掩碼。目前inotify支持的事件類型包括如下幾種
IN_ACCESS
IN_ATTRIB
IN_CLOSE_WRITE
IN_CLOSE_NOWRITE
IN_CREATE
IN_DELETE
IN_DELETE_SELF
IN_MODIFY
IN_MOVE_SELF
IN_MOVED_FROM
IN_MOVED_TO
IN_OPEN
這里面值得注意的是IN_DELETE、IN_MOVE_TO和IN_DELETE_SELF、IN_MOVE_SELF,簡單來說帶有SELF結尾的事件,發生在被關注目錄自身,而不帶SELF的發生在關注對象的子目錄或者子文件之上。例如對於目錄A調用inotify_add_watch,如果目錄A中的文件B被刪除,內核會發出IN_DELETE事件,而目錄A被刪除,內核發出IN_DELETE_SELF事件。
如果決定不再關注某個文件,只需調用inotify_rm_watch(instance_fd, wd)即可,其中的wd為inotify_add_watch的返回值。
設置好了關注文件以及事件類型,剩下的就是inotify事件的處理了。
首先第一步就是要獲取inotify事件,這一步非常簡單,只需要對於instance_fd調用read進行讀取即可。注意,read讀出的數據只是一些字符序列,你要通過強制轉換才能獲得inotify_event
1
2
3
4
5
6
7
|
struct
inotify_event {
int
wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char
name[]
};
|
具體的含義可以使用man命令去看,值得一體的是mask字段和cookie字段。這里的mask字段除了包含事件類型之外,還可能包含其他信息,諸如IN_ISDIR標示事件是否是發生在目錄之上,IN_UMOUNT標示關注對象所在文件系統是否被卸載等。
Windows下也有類似的系統調用ReadDirectoryChanges
原文地址:http://www.cnblogs.com/jimmychange/p/3498862.html