linux使用Inotify监控目录或者文件状态变更

来源:互联网 发布:密码破解软件 编辑:程序博客网 时间:2024/05/17 02:47

转自:http://blog.csdn.net/daiyudong2020/article/details/51695502

基本概念:

Inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。

需求:

1.有一个文件采集进程,需要对日志文件进行采集,日志文件可能会被删除,可能会被移动。

2.我们都知道文件一旦被删除或者移动,那么进程使用原有打开的文件fd就无法继续读取文件数据。

3.那么就需要监控文件的创建,移动,删除等状态,以便重新打开文件,所以需要使用Inotify来做这件事。

源码inotfy.c

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <sys/inotify.h>  
  5. #include <unistd.h>  
  6.   
  7. #define EVENT_NUM 12  
  8. char *event_str[EVENT_NUM] =  
  9. {  
  10. "IN_ACCESS",  
  11. "IN_MODIFY",        //文件修改  
  12. "IN_ATTRIB",  
  13. "IN_CLOSE_WRITE",  
  14. "IN_CLOSE_NOWRITE",  
  15. "IN_OPEN",  
  16. "IN_MOVED_FROM",    //文件移动from  
  17. "IN_MOVED_TO",      //文件移动to  
  18. "IN_CREATE",        //文件创建  
  19. "IN_DELETE",        //文件删除  
  20. "IN_DELETE_SELF",  
  21. "IN_MOVE_SELF"  
  22. };  
  23.   
  24. int main(int argc, char *argv[])  
  25. {  
  26.     int fd;  
  27.     int wd;  
  28.     int len;  
  29.     int nread;  
  30.     char buf[BUFSIZ];  
  31.     struct inotify_event *event;  
  32.     int i;  
  33.   
  34.     // 判断输入参数  
  35.     if (argc < 2) {  
  36.         fprintf(stderr, "%s path\n", argv[0]);  
  37.         return -1;  
  38.     }  
  39.   
  40.     // 初始化  
  41.     fd = inotify_init();  
  42.     if (fd < 0) {  
  43.         fprintf(stderr, "inotify_init failed\n");  
  44.         return -1;  
  45.     }  
  46.   
  47.     /* 增加监听事件 
  48.      * 监听所有事件:IN_ALL_EVENTS 
  49.      * 监听文件是否被创建,删除,移动:IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO 
  50.      */  
  51.     wd = inotify_add_watch(fd, argv[1], IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO);  
  52.     if(wd < 0) {  
  53.         fprintf(stderr, "inotify_add_watch %s failed\n", argv[1]);  
  54.         return -1;  
  55.     }  
  56.   
  57.     buf[sizeof(buf) - 1] = 0;  
  58.     while( (len = read(fd, buf, sizeof(buf) - 1)) > 0 ) {  
  59.         nread = 0;  
  60.         while(len> 0) {  
  61.             event = (struct inotify_event *)&buf[nread];  
  62.             for(i=0; i<EVENT_NUM; i++) {  
  63.                 if((event->mask >> i) & 1) {  
  64.                     if(event->len > 0)  
  65.                         fprintf(stdout, "%s --- %s\n", event->name, event_str[i]);  
  66.                     else  
  67.                         fprintf(stdout, "%s --- %s\n"" ", event_str[i]);  
  68.                 }  
  69.             }  
  70.             nread = nread + sizeof(struct inotify_event) + event->len;  
  71.             len = len - sizeof(struct inotify_event) - event->len;  
  72.         }  
  73.     }  
  74.   
  75.     return 0;  
  76. }  

编译运行:

[cpp] view plain copy
  1. gcc inotfy.c  
  2.   
  3. // 监控当前目录的文件变化  
  4. ./a.out ./  

测试结果:



小结:

1.可以根据需要对代码进行调整测试

2.参考:http://www.ibm.com/developerworks/cn/linux/l-inotify/

3.参考:http://www.jb51.net/article/37420.htm