linux下mtp usb的开发之inotify监听机制

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是:

      还有非常多的事件可以使用。使用man   inotify可以查看所有可以监听的事件。

         mask是上面这些事件的或。例如IN_ACCESS|IN_MODIFY。

         返回值:成功>0,表示监控文件的文件的事件,删除事将这个fd删除,失败-1。
删除监视对象

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

在mtpmain.cpp 


static void inotifyAddWatch() {
    ALOGD("%s\n", __func__);
    inotify_add_watch(mInotifyMediaFd, "/media",
                    IN_CREATE | IN_DELETE);
}

sitemap