如何用c语言实现对目录或是文件进行文件的添加,修改,删除监控(inotify)。

其实通过inotify来实现,具体代码实现如下: 

#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 mmain(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");
    }

    //创建inotify
    mNotifyId = 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;


}

再提拱一种通过epoll配合方式来实现

 

#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 handler
                    if(-1 == inotify_event_handler(mEpollId,mInotifyId))
                    {
                        printf("inotify handler error!\n");
                        return -1;
                    }

                }else
                {
                    printf("read data.....\n");
                    //read content of file
                    readlen = read(gEpollEventArray[i].data.fd, readbuf, 1024);
                    readbuf[readlen] = '\0';
                    printf("read data %s\n",readbuf);
                }

            }

        }

    }

}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值