首先学习Inotify机制,就是Linux系统下对文件目录的监听,如果目录下有文件创建删除都可以被监听到,那这个有什么作用呢?

在Android Input系统中可以实现对设备热插拔的监听。我们先看一个简单的Demo

#include<stdio.h>
#include<assert.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<sys/inotify.h>
#include<limits.h>
#include<fcntl.h>  #define BUF_LEN 1000  void displayEvent(struct inotify_event* tempEvent)
{printf("mask = %d\n",tempEvent->mask); //判断有哪些事件发生if(tempEvent->mask & IN_ACCESS)   printf("IN_ACCESS\n");  if(tempEvent->mask & IN_DELETE_SELF)   printf("IN_DELETE_SELF\n");  if(tempEvent->mask & IN_MODIFY)  printf("IN_MODIFY\n");  if(tempEvent->mask & IN_OPEN)   printf("IN_OPEN\n");}int main(int argc , char** argv)
{int mNotifyId , mWd;char mInfoBuf[BUF_LEN];ssize_t mNumRead;struct inotify_event * mTempEvent; char* p; if(argc < 2){printf("argv error\n");}//创建inotifymNotifyId = inotify_init();if(mNotifyId == -1){printf("notifyInit Failure\n");} //添加对文件的监听mWd = inotify_add_watch(mNotifyId,argv[1],IN_ALL_EVENTS);if(mWd == -1){printf("watch failure \n");}while(1){//监听的路径是否有文件创建删除等消息mNumRead = read(mNotifyId,mInfoBuf,BUF_LEN);if(mNumRead == -1){printf("read error\n");}for(p = mInfoBuf;p < mInfoBuf + mNumRead;){mTempEvent = (struct inotify_event *)p;displayEvent(mTempEvent);p += sizeof(struct inotify_event) + mTempEvent->len;}}return 0;}

Inotify可以监听到哪些事件呢

 可以被监控的事件:有几种事件能够被监控。一些事件,比如 IN_DELETE_SELF 只适用于正在被监控的项目,而另一些,比如 IN_ATTRIB 或者 IN_OPEN 则只适用于监控过的项目,或者如果该项目是目录,则可以应用到其所包含的目录或文件。IN_ACCESS被监控项目或者被监控目录中的条目被访问过。例如,一个打开的文件被读取。IN_MODIFY被监控项目或者被监控目录中的条目被修改过。例如,一个打开的文件被修改。IN_ATTRIB被监控项目或者被监控目录中条目的元数据被修改过。例如,时间戳或者许可被修改。IN_CLOSE_WRITE一个打开的,等待写入的文件或目录被关闭。IN_CLOSE_NOWRITE一个以只读方式打开的文件或目录被关闭。IN_CLOSE一个掩码,可以很便捷地对前面提到的两个关闭事件(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)进行逻辑操作。IN_OPEN文件或目录被打开。IN_MOVED_FROM被监控项目或者被监控目录中的条目被移出监控区域。该事件还包含一个 cookie 来实现 IN_MOVED_FROM 与 IN_MOVED_TO 的关联。IN_MOVED_TO文件或目录被移入监控区域。该事件包含一个针对 IN_MOVED_FROM 的 cookie。如果文件或目录只是被重命名,将能看到这两个事件,如果它只是被移入或移出非监控区域,将只能看到一个事件。如果移动或重命名一个被监控项目,监控将继续进行。参见下面的 IN_MOVE-SELF。IN_MOVE可以很便捷地对前面提到的两个移动事件(IN_MOVED_FROM | IN_MOVED_TO)进行逻辑操作的掩码。IN_CREATE在被监控目录中创建了子目录或文件。IN_DELETE被监控目录中有子目录或文件被删除。IN_DELETE_SELF被监控项目本身被删除。监控终止,并且将收到一个 IN_IGNORED 事件。IN_MOVE_SELF监控项目本身被移动。除了事件标志以外,还可以在 inotify 头文件(/usr/include/sys/inotify.h)中找到其他几个标志。例如,如果只想监控第一个事件,可以在增加监控时设置 IN_ONESHOT 标志。

下面就是Epoll+Inotify的实现

#include <stdio.h>
#include <sys/epoll.h>
#include <sys/inotify.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>/* 定义epoll最大监听的文件数量 */
#define EPOLL_MAX_EVENTS    32#define BUFFER_SIZE     1024
#define ARRAY_LENGTH    128     // 定义数组的长度
#define NAME_LENGTH     128     // 定义文件名长度的限制 struct file_name_fd_desc {  int fd;                         // 文件的描述符  char name[32];                  // 文件名  char base_name[NAME_LENGTH];    // 带绝对路径的文件名
}; static struct epoll_event gEpollEventArray[EPOLL_MAX_EVENTS];/* 定义一个数组用来存放对应文件的文件描述符和文件名 */
static struct file_name_fd_desc gFileFdArray[ARRAY_LENGTH];static int array_index = 0;static char *base_dir;   /*添加文件描述符到Epoll*/
static int add_to_epoll(int epoll_fd, int file_fd)
{int result;struct epoll_event eventItem;memset(&eventItem,0,sizeof(eventItem));eventItem.events=EPOLLIN;eventItem.data.fd = file_fd;result = epoll_ctl(epoll_fd,EPOLL_CTL_ADD,file_fd,&eventItem);   return result;
}/*从Epoll删除文件描述符*/
static  void remove_epoll(int epoll_fd,int file_fd)
{epoll_ctl(epoll_fd,EPOLL_CTL_DEL,file_fd,NULL);
}/*inotify监听到事件的处理逻辑,将新创建的文件添加到epoll,删除的文件从epoll删除*/
static int inotify_event_handler(int epoll_fd,int notify_fd)
{char InfoBuf[BUFFER_SIZE];struct inotify_event *event;char* p;int tmp_fd;int i;memset(InfoBuf,0,BUFFER_SIZE); int result = read(notify_fd,InfoBuf,BUFFER_SIZE);for(p = InfoBuf ; p < InfoBuf + result;){event = (struct inotify_event *)(p);if(event->mask & IN_CREATE){sprintf(gFileFdArray[array_index].name,"%s",event->name);sprintf(gFileFdArray[array_index].base_name,"%s%s",base_dir,event->name);tmp_fd = open(gFileFdArray[array_index].base_name, O_RDWR);if(tmp_fd == -1){printf("open file failure : %s\n",gFileFdArray[array_index].base_name);return -1;}gFileFdArray[array_index].fd = tmp_fd;add_to_epoll(epoll_fd,tmp_fd);array_index += 1;printf("add file to epoll %s\n",event->name);}else  //delete file{for(i = 0 ; i < ARRAY_LENGTH ; i++){ if(!strcmp(gFileFdArray[i].name,event->name)){remove_epoll(epoll_fd,gFileFdArray[i].fd);gFileFdArray[i].fd = 0;memset(gFileFdArray[i].name, 0, sizeof(gFileFdArray[i].name));  memset(gFileFdArray[i].base_name, 0, sizeof(gFileFdArray[i].base_name));printf("delete file to epoll %s\n",event->name);break;  }}}p += sizeof(struct inotify_event) + event->len;    }}int main(int argc,char** argv)
{int mInotifyId;int mEpollId;char readbuf[1024];  int readlen;if(argc != 2){printf("Paramter Error\n");}base_dir = argv[1];//epoll创建mEpollId = epoll_create(1);if(mEpollId == -1){printf("Epoll Create Error\n");return -1;}    mInotifyId = inotify_init();//Observe Directory FILE_CREATE & FILE_DELETE//inotify添加对文件的监听int result = inotify_add_watch(mInotifyId,argv[1],IN_DELETE | IN_CREATE);if(result == -1){printf("File Add Watch Failure\n");return -1;}add_to_epoll(mEpollId,mInotifyId);while(1){result = epoll_wait(mEpollId,gEpollEventArray,EPOLL_MAX_EVENTS,-1);if(result == -1){printf("epoll wait error\n");return -1;}else{ printf("file event happen\n");int i = 0; for(i = 0; i < result; i++){if(gEpollEventArray[i].data.fd == mInotifyId){//inotify event handlerif(-1 == inotify_event_handler(mEpollId,mInotifyId))  {  printf("inotify handler error!\n");  return -1;  }  }else{printf("read data.....\n");  //read content of filereadlen = read(gEpollEventArray[i].data.fd, readbuf, 1024);  readbuf[readlen] = '\0';  printf("read data %s\n",readbuf);    }}}}}

Linux inotify + Epoll实现机制相关推荐

  1. Handler消息机制(一):Linux的epoll机制

    在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序.在linux新的内核中,有了一种替换它的机制,就是epoll. sele ...

  2. linux --- inotify 文件系统变化通知机制

    Linux --- inotify 文件系统变化通知机制 在linux下开发过程中,用户态需要内核提供一些机制,以便用户态能够及时地得知内核或底层硬件设备发生了什么,从而能够更好地管理设备,给用户提供 ...

  3. Linux inotify功能及实现原理【转】

    转自:http://blog.csdn.net/myarrow/article/details/7096460 1. inotify主要功能 它是一个内核用于通知用户空间程序文件系统变化的机制. 众所 ...

  4. linux内核设计与实现 epub_Epoll学习服务器的简单实现-Linux内核Epoll结构

    1.Begins~ 有的人学习linux编程很久,只知道网络编程是socket,bind, listen...,然而这些都是网络通信软件最基本的接口.在某网络公司待了y,也了解到公司的基础就是网络转发 ...

  5. linux socket epoll

    什么是epoll epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改进的poll.当然,这不是2.6内核才有的,它是在2.5.44内核中被引进的(epoll(4) is a new A ...

  6. netty的epoll和linux的epoll是如何实现的

    1.linux的epoll epoll 是Linux内核中的一种可扩展IO事件处理机制,最早在 Linux 2.5.44内核中引入,可被用于代替POSIX select 和 poll 系统调用,并且在 ...

  7. Linux inotify

    简述 Linux inotify是一种监控文件系统中文件和目录变化的机制,能够实时地监视文件和目录的变化并通知相应的进程. 在Linux系统中,文件系统的访问和管理是通过系统调用进行的.inotify ...

  8. Windows 平台下面的IOCP技术 Linux下面Epoll 还有FreeBSD下面Kqueue的应用了。跨平台库行业里面最出名的莫过于ACE、ASIO(Boos公司)两大支持库支持IOCP

    http://wenku.baidu.com/view/4117460502020740be1e9b3c.html 游戏服务器集群 自从2003年开发VOIP Radius Server以及修改Gnu ...

  9. Linux inotify功能及原理(inotify_init、inotify_add_watch、inotify_rm_watch、read)

    1. inotify主要功能 它是一个内核用于通知用户空间程序文件系统变化的机制. 开源社区提出用户态需要内核提供一些机制,以便用户态能够及时地得知内核或底层硬件设备发生了什么,从而能够更好地管理设备 ...

最新文章

  1. Ubuntu通过路由器上网的配置
  2. 在c 语言中stdio,C语言中,什么时候用到stdio.h之外的解释文件
  3. mysql 开启守护进程_[求助]Linux上MySQL Server 5.6 安装后无法启动守护进程
  4. mysql int 11 java_mysql中int(11)列的大小(以字节为单位)是多少?
  5. Fullpage参数说明
  6. hdoj 1285 确定比赛名次 【拓扑排序】
  7. 计算机编程pdf百度云,计算机编程基础.pdf
  8. android怎么阿看手机是移动联通还是电信的网络,GSM是联通、移动还是电信的网络?...
  9. python爬取公众号,用最简单的方式爬虫
  10. 解决在IE下“JSON”未定义的有关问题
  11. 远程连接桌面报:这可能是由于credssp加密oracle修正
  12. 那些年-SAP固定资产导入AS91 OASV
  13. Matlab 2016 超详细安装教程
  14. html 卫星地图显示地名,卫星图看:河南10个名字非常好听的县(区),你认识几个?...
  15. HP惠普服务器做RAID
  16. java实现微信企业号API服务端调用封装
  17. qconshanghai2015
  18. 安徽师大附中%你赛day3T1 怜香惜玉 解题报告
  19. GO语言开发天天生鲜项目第三天 用户模块开发
  20. libevent库bufferevent事件实现socket通信

热门文章

  1. 手机备忘录不小心删除了如何恢复
  2. 老男孩python全栈s21day02笔记
  3. maui,gird添加背景图片
  4. iOS 照片涂鸦功能的实现
  5. vivo y73s参数配置 vivo Y73s多少钱
  6. RFID犯人手环点名定位系统管理方案
  7. v86.01 鸿蒙内核源码分析 (静态分配篇) | 很简单的一位小朋友 | 百篇博客分析 OpenHarmony 源码
  8. 无刷电机FOC控制(自己的理解,不一定正确,仅供参考)
  9. 关于App启动加载广告页面思路
  10. Python:matplotlib绘制线条图