inotify和epoll

参考EventHub.cpp

1、初始化inotify

int mINotifyFd = inotify_init();

2、将要监测的目录添加到inotify

int result = inotify_add_watch(mINotifyFd, argv[1], IN_DELETE | IN_CREATE);

3、读inotify有没有event

#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <stdio.h>

int read_process_inotify_fd(int fd)
{
    int res;
    char event_buf[512];
    int event_size;
    int event_pos = 0;
    struct inotify_event *event;
      res = read(fd, event_buf, sizeof(event_buf));
      if(res < (int)sizeof(*event)) {
              if(errno == EINTR)
                  return 0;
              printf("could not get event, %s
", strerror(errno));
              return -1;
      }
      while(res >= (int)sizeof(*event)) {
        event = (struct inotify_event *)(event_buf + event_pos);
        //printf("%d: %08x "%s"
", event->wd, event->mask, event->len ? event->name : "");
        if(event->len) {
           
            if(event->mask & IN_CREATE) {
                printf("create file: %s
", event->name);
            } else {
                printf("delete file: %s
", event->name);
            }
        }
        event_size = sizeof(*event) + event->len;
        res -= event_size;
        event_pos += event_size;
    }
    return 0;
      
}

int main(int argc, char **argv)
{
     int ret;
     if (argc != 2) {
         printf("Usage: %s <dir>
", argv[0]);
         return -1;
     }

    int mINotifyFd = inotify_init();
    int result = inotify_add_watch(mINotifyFd, argv[1], IN_DELETE | IN_CREATE);
    if (result < 0) {
        printf("inotify_add_watch error
");
        return -1;
    }
    while (1) {
         ret = read_process_inotify_fd(mINotifyFd);
         if (ret) {
             printf("read_process_inotify_fd error
");
             return -1;
         }
    }

    return 0;
}

 1、创建epoll

int mEpollFd = epoll_create(5);

2、打开fifo路径,添加到epoll

3、epoll_wait

4、读数据

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <unistd.h>

/*
 * 
           typedef union epoll_data {
               void    *ptr;
               int      fd;
               uint32_t u32;
               uint64_t u64;
           } epoll_data_t;

           struct epoll_event {
               uint32_t     events;    /* Epoll events */
 /*              epoll_data_t data;      /* User data variable */
 /*          };
 */

#define MAXEVENTS     10
#define MAXLEN        512
static struct epoll_event eventItem[MAXEVENTS];

int epoll_add_watch(int mEpollFd, int fd)
{
    struct epoll_event eventItem;
    memset(&eventItem, 0, sizeof(eventItem));
    eventItem.events = EPOLLIN;
    eventItem.data.fd = fd;
    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem);
    return result;
}

int main(int argc, char **argv)
{
    int res;
    char buf[MAXLEN];
    if (argc < 2) {
         printf("Usage: ./epoll <fifo1> <fifo2> ...
");
         return -1;
    }
    int mEpollFd = epoll_create(5);  //最多监听5个文件
    if (mEpollFd < 0) {
        printf("epoll_create error
");
        return -1;
    }

    int i;
    for (i = 1; i < argc; i++) {
         int fd = open(argv[i], O_RDWR);
         if (fd < 0) {
              printf("open %s error
", argv[i]);
              return -1;
         }
         res = epoll_add_watch(mEpollFd, fd);
         if (res) {
            printf("epoll_add_watch error
");
            return -1;
         }
    }

    while (1) {
          int poll_result = epoll_wait(mEpollFd, eventItem, MAXEVENTS, -1);
          for (i = 0; i < poll_result; i++) {
               int len = read(eventItem[i].data.fd, buf, MAXLEN);
               buf[len] = '';
               printf("get data : %s
", buf);
          }    
    }
    return 0;
    
}

inotify和epoll同时使用,即能监测到有没有新的文件创建,还能读出文件内容

#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/epoll.h>

static int mEpollFd;
#define MAXEVENTS     10
#define MAXLEN        512
#define MAXFD         512

static char *DIR_NAME;
static struct epoll_event eventItem[MAXEVENTS];

char *file_and_fd[MAXFD];

int epoll_add_watch(int fd)
{
    struct epoll_event eventItem;
    memset(&eventItem, 0, sizeof(eventItem));
    eventItem.events = EPOLLIN;
    eventItem.data.fd = fd;
    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem);
    return result;
}

void epoll_rm_watch(int fd)
{
    epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
    
}

//打开文件并加入epoll监听
int open_file_add_epoll(char *filename)
{
         int fd = open(filename, O_RDWR);
         if (fd < 0) {
              printf("open %s error
", filename);
              return -1;
         }
         file_and_fd[fd] = filename;
         int res = epoll_add_watch(fd);
         if (res) {
            printf("epoll_add_watch error
");
            return -1;
         }
}

int find_fd(char *name)
{
    int i;
    for (i = 0; i < MAXFD; i++) {
        if (strcmp(file_and_fd[i], name) == 0)
            return i;
    }
    return -1;
}

int read_process_inotify_fd(int fd)
{
    int res;
    char file_path[20];
    char event_buf[512];
    int event_size;
    int event_pos = 0;
    struct inotify_event *event;
      res = read(fd, event_buf, sizeof(event_buf));
      if(res < (int)sizeof(*event)) {
              if(errno == EINTR)
                  return 0;
              printf("could not get event, %s
", strerror(errno));
              return -1;
      }
      while(res >= (int)sizeof(*event)) {
        event = (struct inotify_event *)(event_buf + event_pos);
        //printf("%d: %08x "%s"
", event->wd, event->mask, event->len ? event->name : "");
        if(event->len) {
            sprintf(file_path, "%s/%s", DIR_NAME, event->name);
            if(event->mask & IN_CREATE) {
                printf("create file: %s
", event->name);
                open_file_add_epoll(file_path);
            } else {
                printf("delete file: %s
", event->name);
                int file_fd = find_fd(file_path);
                epoll_rm_watch(file_fd);
            }
        }
        event_size = sizeof(*event) + event->len;
        res -= event_size;
        event_pos += event_size;
    }
    return 0;
      
}

int main(int argc, char **argv)
{
     int ret;
     int i;
     if (argc != 2) {
         printf("Usage: %s <dir>
", argv[0]);
         return -1;
     }
     
    char buf[MAXLEN];

    int mINotifyFd = inotify_init();
    int result = inotify_add_watch(mINotifyFd, argv[1], IN_DELETE | IN_CREATE);
    if (result < 0) {
        printf("inotify_add_watch error
");
        return -1;
    }
    DIR_NAME = argv[1];
    mEpollFd = epoll_create(5);  
    if (mEpollFd < 0) {
        printf("epoll_create error
");
        return -1;
    }
    
    epoll_add_watch(mINotifyFd);  //监测目录
    
    while (1) {
        
         int poll_result = epoll_wait(mEpollFd, eventItem, MAXEVENTS, -1);
        
         for (i = 0; i < poll_result; i++) {
             if (eventItem[i].data.fd == mINotifyFd) {    //有新文件创建, 目录argv[1]里面有变化
                 ret = read_process_inotify_fd(mINotifyFd);
                 if (ret) {
                     printf("read_process_inotify_fd error
");
                     return -1;
                 }
            }else{                             //文件的内容有变化
                 int len = read(eventItem[i].data.fd, buf, MAXLEN);
                 buf[len] = '';
                 printf("get data : %s
", buf);
            }
               
         }
    }

    return 0;
}
原文地址:https://www.cnblogs.com/zhu-g5may/p/10551055.html