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\n", strerror(errno)); return -1; } while(res >= (int)sizeof(*event)) { event = (struct inotify_event *)(event_buf + event_pos); //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); if(event->len) { if(event->mask & IN_CREATE) { printf("create file: %s\n", event->name); } else { printf("delete file: %s\n", 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>\n", 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\n"); return -1; } while (1) { ret = read_process_inotify_fd(mINotifyFd); if (ret) { printf("read_process_inotify_fd error\n"); 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> ...\n"); return -1; } int mEpollFd = epoll_create(5); //最多监听5个文件 if (mEpollFd < 0) { printf("epoll_create error\n"); return -1; } int i; for (i = 1; i < argc; i++) { int fd = open(argv[i], O_RDWR); if (fd < 0) { printf("open %s error\n", argv[i]); return -1; } res = epoll_add_watch(mEpollFd, fd); if (res) { printf("epoll_add_watch error\n"); 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] = '\0'; printf("get data : %s\n", 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\n", filename); return -1; } file_and_fd[fd] = filename; int res = epoll_add_watch(fd); if (res) { printf("epoll_add_watch error\n"); 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\n", strerror(errno)); return -1; } while(res >= (int)sizeof(*event)) { event = (struct inotify_event *)(event_buf + event_pos); //printf("%d: %08x \"%s\"\n", 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\n", event->name); open_file_add_epoll(file_path); } else { printf("delete file: %s\n", 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>\n", 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\n"); return -1; } DIR_NAME = argv[1]; mEpollFd = epoll_create(5); if (mEpollFd < 0) { printf("epoll_create error\n"); 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\n"); return -1; } }else{ //文件的内容有变化 int len = read(eventItem[i].data.fd, buf, MAXLEN); buf[len] = '\0'; printf("get data : %s\n", buf); } } } return 0; }