如何使用inotify_init,inotify_add_watch,inotify_rm_watch,read编写监控程序

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

2010-12-20 10:00:29|  分类: Linux系统编程 |  标签: |字号 订阅

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

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

 

inotify的用户接口原型主要有以下3个:
#include  <sys/inotify.h>

初始化: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是:

             如何使用inotify_init,inotify_add_watch,inotify_rm_watch编写程序 - xychenbaihu@yeah - 无影的博客

             还有非常多的事件可以使用。使用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 <stdio.h>   
#include <unistd.h>   
#include <sys/select.h>   
#include <errno.h>   
#include <sys/inotify.h>   
  
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 <file/dir>\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))) < 0) && (errno == EINTR));       //没有读取到事件。
           while (index < len) 

           {   
                  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;   
}  

             

            


  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 epoll 和 inotify 监控文件,需要进行以下步骤: 1. 创建一个 epoll 实例并将其添加到监听文件描述符列表中。 2. 创建一个 inotify 实例并将其添加到 epoll 实例中。 3. 使用 inotify_add_watch 函数添加要监视的文件或目录。 4. 启动 epoll 循环,并等待事件发生。 5. 当有事件发生时,使用 epoll_wait 函数获取事件列表。 6. 遍历事件列表,处理每个事件。如果是 inotify 事件,则读取事件并处理它。 7. 如果需要继续监视文件,则重复步骤 4-6。 下面是一个简单的示例代码,用于监视目录中的文件创建或删除事件: ```c #include <stdio.h> #include <stdlib.h> #include <sys/epoll.h> #include <sys/inotify.h> #define MAX_EVENTS 10 #define EVENT_SIZE (sizeof (struct inotify_event)) #define BUF_LEN (MAX_EVENTS * (EVENT_SIZE + 16)) int main(int argc, char const *argv[]) { int fd, wd, epfd, n, i; char buf[BUF_LEN]; struct epoll_event event; struct epoll_event events[MAX_EVENTS]; // create an inotify instance fd = inotify_init(); if (fd < 0) { perror("inotify_init"); exit(EXIT_FAILURE); } // add the inotify instance to epoll epfd = epoll_create(1); if (epfd < 0) { perror("epoll_create"); exit(EXIT_FAILURE); } event.data.fd = fd; event.events = EPOLLIN | EPOLLET; if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event) < 0) { perror("epoll_ctl"); exit(EXIT_FAILURE); } // add directory to watch list wd = inotify_add_watch(fd, "/path/to/directory", IN_CREATE | IN_DELETE); if (wd < 0) { perror("inotify_add_watch"); exit(EXIT_FAILURE); } while (1) { // wait for events n = epoll_wait(epfd, events, MAX_EVENTS, -1); if (n < 0) { perror("epoll_wait"); break; } for (i = 0; i < n; i++) { if (events[i].data.fd == fd) { // read inotify events int len = read(fd, buf, BUF_LEN); if (len < 0) { perror("read"); break; } char *p = buf; while (p < buf + len) { struct inotify_event *event = (struct inotify_event *) p; printf("event: %s\n", event->name); p += sizeof(struct inotify_event) + event->len; } } } } // cleanup inotify_rm_watch(fd, wd); close(fd); close(epfd); return 0; } ``` 在此示例中,我们创建了一个 inotify 实例并将其添加到 epoll 实例中。然后,我们使用 inotify_add_watch 函数添加要监视的目录,并指定要监视的事件类型(在本例中为文件创建和删除事件)。最后,我们启动 epoll 循环,并等待事件发生。当事件发生时,我们读取 inotify 事件并处理它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值