项目中,要实现用户通过网页设置參数,后台接收数据然后写串口。

网页写数据到本地文件,使用inotify监控文件的IN_MODIFY事件。当文件被改动,然后触发写串口事件。

第一个程序只把要监控的文件增加watch_list中,运行程序。发现select返回。只能检測到文件被改动,

可是假设同一时候监控多个文件。却不能区分是哪个文件被修改了。

/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp” directory*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <linux/inotify.h> #define FILE1 "request"
#define FILE2 "time"
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) int main( )
{
int length,i=0;
int fd,maxfd;
int wd1;
int wd2;
int ret;
fd_set rfds;
fd_set wfds;
struct timeval tv;
char buffer[EVENT_BUF_LEN]; /*creating the INOTIFY instance*/
fd = inotify_init(); /*checking for error*/
if ( fd < 0 )
{
perror( "inotify_init" );
exit(-1);
} /*adding the “/tmp” directory into watch list. Here, the suggestion is to validate the existence of the directory before adding into monitoring list.*/
wd1 = inotify_add_watch( fd,FILE1, IN_MODIFY);
if(wd1 < 0)
{
perror("inotify_add_watch");
exit(-1);
} wd2 = inotify_add_watch( fd,FILE2, IN_MODIFY);
if(wd2 < 0)
{
perror("inotify_add_watch");
exit(-1);
}
/*read to determine the event change happens on “/tmp” directory. Actually this read blocks until the change event occurs*/ while(1)
{
printf("begining while\n");
FD_ZERO(&rfds);
FD_SET(fd,&rfds);
maxfd = fd + 1;
tv.tv_sec = 10;
tv.tv_usec = 0; printf("waiting select ...\n");
ret = select(maxfd,&rfds,NULL,NULL,&tv);
switch(ret)
{
case -1:
fprintf(stderr,"select failed\n");
break;
case 0:
fprintf(stderr,"select timeout...\n");
continue;
default:
fprintf(stderr,"fd is readable.\n");
length = read(fd,buffer,EVENT_BUF_LEN);
printf("length=%d\n",length);
if(length < 0)
{
perror("read");
exit(-1);
}
while(i < length)
{
fprintf(stderr,"inside while ...\n");
struct inotify_event *event = (struct inotify_event*)&buffer[i];
printf("event->len = %d\n",event->len);
if(event->len)
{
if(event->mask & IN_MODIFY)
{
printf("detected file %s modified.\n",event->name);
}
}
i += EVENT_SIZE + event->len;
}
i = 0;
inotify_rm_watch(fd,wd1);
inotify_rm_watch(fd,wd2);
close(fd);
fd = inotify_init();
wd1 = inotify_add_watch( fd,FILE1, IN_MODIFY);
wd2 = inotify_add_watch( fd,FILE2, IN_MODIFY);
break;
/*
printf("detected file modified\n");
sleep(1);
inotify_rm_watch(fd,wd);
close(fd);
fd = inotify_init();
wd = inotify_add_watch( fd,TEST_FILE, IN_MODIFY);
break;
*/
}
printf("break switch\n"); }
inotify_rm_watch(fd,wd1);
inotify_rm_watch(fd,wd2);
close(fd); return 0;
}

struct inotify_event {

               int      wd;       /* Watch descriptor */

               uint32_t mask;     /* Mask of events */

               uint32_t cookie;   /* Unique cookie associating related

                                     events (for rename(2)) */

               uint32_t len;      /* Size of name field */

               char     name[];   /* Optional null-terminated name */

           };





       wd identifies the watch for which this event occurs.  It is one of the watch descriptors returned by a previous call to inotify_add_watch(2).





       mask contains bits that describe the event that occurred (see below).





       cookie is a unique integer that connects related events.  Currently this is only used for rename events, and allows the resulting  pair  of  IN_MOVE_FROM

       and IN_MOVE_TO events to be connected by the application.





       The  name  field is only present when an event is returned for a file inside a watched directory; it identifies the file pathname relative to the watched

       directory.  This pathname is null-terminated, and may include further null bytes to align subsequent reads to a suitable address boundary.





       The len field counts all of the bytes in name, including the null bytes; the length of each inotify_event structure is thus sizeof(inotify_event)+len.





       The behavior when the buffer given to read(2) is too small to return information about the next event depends on the kernel version:  in  kernels  before

       2.6.21, read(2) returns 0; since kernel 2.6.21, read(2) fails with the error EINVAL.

又细致阅读了man inotify,发现仅仅有把文件夹加入到watch_list,才干获得是文件夹中的哪一个文件被改动了。

/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp” directory*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <linux/inotify.h> #define MONITOR_PATH "/home/lucifer/working/2015_08_19"
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) int main( )
{
int length,i=0;
int fd,maxfd;
int wd1;
int ret;
fd_set rfds;
fd_set wfds;
struct timeval tv;
char buffer[EVENT_BUF_LEN]; /*creating the INOTIFY instance*/
fd = inotify_init(); /*checking for error*/
if ( fd < 0 )
{
perror( "inotify_init" );
exit(-1);
} /*adding the “/tmp” directory into watch list. Here, the suggestion is to validate the existence of the directory before adding into monitoring list.*/
wd1 = inotify_add_watch( fd,MONITOR_PATH, IN_MODIFY);
if(wd1 < 0)
{
perror("inotify_add_watch");
exit(-1);
} /*read to determine the event change happens on “/tmp” directory. Actually this read blocks until the change event occurs*/ while(1)
{
printf("begining while\n");
FD_ZERO(&rfds);
FD_SET(fd,&rfds);
maxfd = fd + 1;
tv.tv_sec = 10;
tv.tv_usec = 0; printf("waiting select ...\n");
ret = select(maxfd,&rfds,NULL,NULL,&tv);
switch(ret)
{
case -1:
fprintf(stderr,"select failed\n");
break;
case 0:
fprintf(stderr,"select timeout...\n");
continue;
default:
fprintf(stderr,"fd is readable.\n");
length = read(fd,buffer,EVENT_BUF_LEN);
printf("length=%d\n",length);
if(length < 0)
{
perror("read");
exit(-1);
}
while(i < length)
{
fprintf(stderr,"inside while ...\n");
struct inotify_event *event = (struct inotify_event*)&buffer[i];
printf("event->len = %d\n",event->len);
if(event->len)
{
if(event->mask & IN_MODIFY)
{
printf("detected file %s modified.\n",event->name);
}
}
i += EVENT_SIZE + event->len;
}
i = 0;
inotify_rm_watch(fd,wd1);
close(fd);
fd = inotify_init();
wd1 = inotify_add_watch( fd,MONITOR_PATH, IN_MODIFY);
break;
/*
printf("detected file modified\n");
sleep(1);
inotify_rm_watch(fd,wd);
close(fd);
fd = inotify_init();
wd = inotify_add_watch( fd,TEST_FILE, IN_MODIFY);
break;
*/
}
printf("break switch\n"); }
inotify_rm_watch(fd,wd1);
close(fd); return 0;
}

caution:当检測文件的IN_MODIFY事件的时候,会发现IN_MODIFY会触发多次

以下是原因

  • Q: What is the difference between IN_MODIFY and IN_CLOSE_WRITE?



    The IN_MODIFY event is emitted on a file content change (e.g. via the write() syscall) while IN_CLOSE_WRITEoccurs on closing the changed file. It means each change operation causes one IN_MODIFY event (it may occurmany times during manipulations with an open
    file) whereas IN_CLOSE_WRITE is emitted only once (on closingthe file).

引用地址:http://inotify.aiken.cz/?section=inotify&page=faq

Linux下使用inotify实现对文件的监控的更多相关文章

  1. linux设置rsync+inotify实时同步文件

    linux设置rsync+inotify实时同步文件   应用场景: 同步接收方:test01 接收目录:/opt/software/test/a/ 同步发起方:test02 同步目录:/opt/so ...

  2. linux 下C语言编程库文件处理与Makefile编写

    做开发快3年了,在linux下编译安装软件算是家常便饭了.就拿gcc来说,都有不下10次了,可基本每次都会碰到些奇奇怪怪的问题.看来还是像vs.codeblocks这样的ide把人弄蠢了.便下定决心一 ...

  3. Linux下用rm删除的文件的恢复方法

    Linux下用rm删除的文件的恢复方法_Linux教程_Linux公社-Linux系统门户网站https://www.linuxidc.com/Linux/2008-08/14744.htm linu ...

  4. linux下查找指定后缀的文件

    1.linux下查找指定后缀的文件 例如查找当前目录下的所有后缀名时.c或.h的文件 find  .  -type f -regex  ".*\.\(c\|h\)"

  5. Linux下自动清除MySQL日志文件

    MySQL运行过程中会生成大量的日志文件,占用不少空间,修改my.cnf文件配置bin-log过期时间,在Linux下自动清除MySQL日志文件 [mysqld] expire-logs-days= ...

  6. Linux下的文件结构,及对应文件夹的作用

    Linux下的文件结构,及对应文件夹的作用 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基点,比 ...

  7. linux下添加用户并将文件夹授权给某一个用户

    ### linux下添加用户并将文件夹授权给某一个用户 背景:在做一个项目时,需要外包的前端人员调试测试环境的页面,但是又不能给他服务器的账号信息,就在服务器上新添加一个子账户,再给这个账户项目文件的 ...

  8. Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身

    Linux下的命令,删除文件夹下的所有文件,而不删除文件夹本身 rm -rf *

  9. linux 下用find命令查找文件,rm命令删除文件

    linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...

随机推荐

  1. MySQL数据库文件

    MySQL数据库文件 本文档从MySQL数据库和存储引擎层面介绍各种类型的文件. 参数文件(my.cnf) 错误日志(error log) 二进制日志文件(binary log) 慢查询日志(slow ...

  2. Django框架基础知识10-内置分页系统

    from django.shortcuts import render, redirect, reversefrom datetime import datetime# Create your vie ...

  3. Farthest Nodes in a Tree (求树的直径)

    题目链接,密码:hpu Description Given a tree (a connected graph with no cycles), you have to find the farthe ...

  4. 关于Hibernate中No row with the given identifier exists问题的原因及解决

    今天遇到一个bug,截图如下 有两张表,table1和table2.产生此问题的原因就是table1里做了关联<one-to-one>或者<many-to-one unique=&q ...

  5. Linux如何查看CPU负载

    负载(load)是Linux机器的一个重要指标,直观了反应了机器当前的状态.如果机器负载过高,那么对机器的操作将难以进行. linux的负载高,主要是由于CPU使用.内存使用.IO消耗三部分构成.任意 ...

  6. zoj 1763 A Simple Question of Chemistry

    A Simple Question of Chemistry Time Limit: 2 Seconds      Memory Limit: 65536 KB Your chemistry lab ...

  7. C#静态构造函数和非静态构造函数

    // 使用静态构造函数时,需要注意几点 //1. 一个类中,最多只能有一个静态构造函数,不允许静态构造函数的重载: //2. 不能加任何访问修饰符(public/private/internale等) ...

  8. [luoguP2513] [HAOI2009]逆序对数列(DP)

    传送门 f[i][j]表示前i个数,逆序对数为j的答案 则DP方程为: f[1][0] = 1; for(i = 2; i <= n; i++) for(j = 0; j <= m; j+ ...

  9. [luoguP1773] 符文之语_NOI导刊2010提高(02)(DP)

    传送门 f[i][j]表示前i个数余数为j的最优解 sum[i][j]表示字符串i~j所构成的数 #include <cstdio> #include <cstring> #d ...

  10. bzoj2190 [SDOI2008]仪仗队 - 筛法 - 欧拉函数

    作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图).    ...