inotify只能监控单层目录变化,不能监控子目录中的变化情况。
如果需要监控子目录,需要在调用inotify_add_watch(int fd, char *dir, int mask):int建立监控时,递归建立子目录的监控,伪代码如下
void addwatch(int fd, char *dir, int mask)
{
wd = inotify_add_watch(fd, dir, mask);
向目录集合加入(wd, dir);
for (dir下所有的子目录subdir)
addwatch(fd, subdir, mask);
}
这样就可以得到一个目录集合,其中每一个wd对应一个子目录。
当你调用read获取信息时,可以得到一个下面的结构体
struct inotify_event
{
int wd; /* Watch descriptor. */
uint32_t mask; /* Watch mask. */
uint32_t cookie; /* Cookie to synchronize two events. */
uint32_t len; /* Length (including NULs) of name. */
char name __flexarr; /* Name. */
};
其中,通过event->wd和刚才记录的目录集合可以知道变动的具体子目录。
event->name为具体的文件名称。
event->name是一个char name[0]形式的桩指针,具体的name占据的长度可以由event->len得出 我的监控部分代码如下:
enum {EVENT_SIZE = sizeof(struct inotify_event)};
enum {BUF_SIZE = (EVENT_SIZE + 16) << 10};
void watch_mon(int fd)
{
int i, length;
void *buf;
struct inotify_event *event;
buf = malloc(BUF_SIZE); while ((length = read(fd, buf, BUF_SIZE)) >= 0)
{
i = 0;
while (i < length)
{
event = buf + i;
if (event->len)
具体处理函数(event);
i += EVENT_SIZE + event->len;
}
}
close(fd);
exit(1);
}
在你的具体处理函数中,通过wd辨识子目录,通过name辨识文件 这是利用C++STLmap写的一个范例,可以监视当前目录下(含子目录)的变化,创建,删除过程(新建立的目录不能监视,只能通过监视到创建新目录的事件后重新初始化监视表)
新版1.1.0,可以监视创建的子目录,方法是,当do_action探测到新目录创建的动作时,调用inotify_add_watch追加新的监视
/*
Copyright (C) 2010-2011 LIU An (SuperHacker@china.com.cn) This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <errno.h>
#include <dirent.h> #include <map>
#include <string>
using namespace std; void addwatch(int, char*, int);
static int filter_action(uint32_t mask);
int watch_init(int mask, char *root);
void addwatch(int fd, char *dir, int mask);
static void do_action(int fd, struct inotify_event *event);
void watch_mon(int fd);
static void send_mess(char *name, char *act, int ewd);
void append_dir(int fd, struct inotify_event *event, int mask); map<int, string> dirset; enum{MASK = IN_MODIFY | IN_CREATE | IN_DELETE}; int main(int argc, char **argv)
{
int fd;
if (argc != 2)
{
fprintf(stderr, "Usage: %s dir\n", argv[0]);
exit(1);
} fd = watch_init(MASK, argv[1]);
watch_mon(fd); return 0;
} int watch_init(int mask, char *root)
{
int i, fd; if ((fd = inotify_init()) < 0)
perror("inotify_init");
addwatch(fd, root, mask);
return fd;
} void addwatch(int fd, char *dir, int mask)
{
int wd;
char subdir[512];
DIR *odir;
struct dirent *dent; if ((odir = opendir(dir)) == NULL)
{
perror("fail to open root dir");
exit(1);
}
wd = inotify_add_watch(fd, dir, mask);
dirset.insert(make_pair(wd, string(dir))); errno = 0;
while ((dent = readdir(odir)) != NULL)
{
if (strcmp(dent->d_name, ".") == 0
|| strcmp(dent->d_name, "..") == 0)
continue;
if (dent->d_type == DT_DIR)
{
sprintf(subdir, "%s/%s", dir, dent->d_name);
addwatch(fd, subdir, mask);
}
} if (errno != 0)
{
perror("fail to read dir");
exit(1);
} closedir (odir);
} enum {EVENT_SIZE = sizeof(struct inotify_event)};
enum {BUF_SIZE = (EVENT_SIZE + 16) << 10}; void watch_mon(int fd)
{
int i, length;
void *buf;
struct inotify_event *event;
buf = malloc(BUF_SIZE); while ((length = read(fd, buf, BUF_SIZE)) >= 0)
{
i = 0;
while (i < length)
{
event = (struct inotify_event*)(buf + i);
if (event->len)
do_action(fd, event);
i += EVENT_SIZE + event->len;
}
}
close(fd);
exit(1);
} static char action[][10] =
{
"modified",
"accessed",
"created",
"removed"
}; enum{NEWDIR = IN_CREATE | IN_ISDIR}; static void do_action(int fd, struct inotify_event *event)
{
int ia, i; if ((ia = filter_action(event->mask)) < 0)
return; if ((event->mask & NEWDIR) == NEWDIR)
append_dir(fd, event, MASK); send_mess(event->name, action[ia], event->wd);
} void append_dir(int fd, struct inotify_event *event, int mask)
{
char ndir[512];
int wd; sprintf(ndir, "%s/%s", dirset.find(event->wd)->second.c_str(),
event->name);
wd = inotify_add_watch(fd, ndir, mask);
dirset.insert(make_pair(wd, string(ndir)));
} static int filter_action(uint32_t mask)
{
if (mask & IN_MODIFY)
return 0;
if (mask & IN_ACCESS)
return 1;
if (mask & IN_CREATE)
return 2;
if (mask & IN_DELETE)
return 3;
return -1;
} static void send_mess(char *name, char *act, int ewd)
{
char format[] = "%s was %s.\n";
char file[512]; sprintf(file, "%s/%s", dirset.find(ewd)->second.c_str(), name); printf(format, file, act);
}

inotify监听文件夹的变动的更多相关文章

  1. 使用Node.JS监听文件夹变化

    使用Node.JS监听文件夹改变有许多应用场合,比如: 构建自动编绎工具 当源文件改变时,自动运行build过程,比如当你写CoffeeScript文件或SASS CSS文件时,保存之后可即时生成对应 ...

  2. nodejs 监听文件夹变化的模块

    使用Node.JS监听文件夹变化 fs.watch 其中Node.JS的文件系统也可侦听某个目录的改变, 如fs.watch   其中fs.watch的最大缺点就是不支持子文件夹的侦听,并且在很多情况 ...

  3. inotify监听文件

    inotify监听文件并通知 static int inotify_dbfile(const char *spFromRule, const char *spDevFile) { int inotif ...

  4. c# 监听文件夹动作

    static FileSystemWatcher watcher = new FileSystemWatcher(); /// <summary>        /// 初始化监听     ...

  5. Java_监听文件夹或者文件是否有变动

    package org.testWatch.Watch; import java.nio.file.FileSystems; import java.nio.file.Path; import jav ...

  6. kafka flumn sparkstreaming java实现监听文件夹内容保存到Phoenix中

    ps:具体Kafka Flumn SparkStreaming的使用  参考前几篇博客 2.4.6.4.1 配置启动Kafka (1) 在slave机器上配置broker 1) 点击CDH上的kafk ...

  7. Java_监听器监听文件夹变动

    package demo4; import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Path ...

  8. java 监听文件或文件夹变化

    今天遇到一个新需求,当从服务器下载文件后用指定的本地程序打开,不知道何时文件下载完成,只能考虑监听文件夹,当有新文件创建的时候打开指定程序. 在此给出一个完整的下载和打开过程: 1.下载文件 jsp页 ...

  9. 如何使用NodeJs来监听文件变化

    1.前言 在我们调试修改代码的时候,每修改一次代码,哪怕只是很小的修改,我们都需要手动重新build文件,然后再运行代码,看修改的效果,这样的效率特别低,对于开发者来说简直不能忍. 2.构建自动编译工 ...

随机推荐

  1. BZOJ 4765 普通计算姬 (分块 + BIT)

    4765: 普通计算姬 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 1547  Solved: 329[Submit][Status][Discus ...

  2. Spring MVC 3 表单中文提交post请求和get请求乱码问题的解决方法

    在spring mvc 3.0 框架中,通过JSP页面.HTML页面以POST方式提交表单时,表单的参数传递到对应的servlet后会出现中文显示乱码的问题.解决办法可采用spring自带的过滤技术, ...

  3. php 类与对象 面向对象编程 简单例子

    <?php class Foo { //类 名称为Foo public $aMemberVar = 'aMemberVar Member Variable'; //类变量 public $aFu ...

  4. Spring通过注解配置Bean

    @Component: 基本注解, 标识了一个受 Spring 管理的组件@Repository: 标识持久层组件@Service: 标识服务层(业务层)组件@Controller: 标识表现层组件 ...

  5. 回文(palindrome)

    如果一个字符串忽略标点符号.大小写和空格,正着读和反着读一模一样,那么这个字符串就是palindrome(回文).

  6. 图解Eclipse中配置Maven并创建Maven的Web工程

      打开eclipse,Windows->Preferences,如下图所示: 2 在Preferences作如下配置,如下图所示: 3 配置完Maven的安装目录后,还需要配置Maven的配置 ...

  7. TypeScript开发环境搭建(Visual studio code)

    使用Visual Studio Code搭建TypeScript开发环境 1.TypeScript是干什么的 ? TypeScript是由微软Anders Hejlsberg(安德斯·海尔斯伯格,也是 ...

  8. Max Sum—hdu1003(简单DP) 标签: dp 2016-05-05 20:51 92人阅读 评论(0)

    Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. ASP.NET Web API 框架研究 服务容器 ServicesContainer

    ServicesContainer是一个服务的容器,可以理解为—个轻量级的IoC容器,其维护着一个服务接口类型与服务实例之间的映射关系,可以根据服务接口类型获取对应的服务实例.构成ASP.NET We ...

  10. javascript Object.create()究竟发生了什么

      这是我在博客园的第一篇博客,早上看了一个大牛的博客,关于javascript继承的,对于大牛使用Object.create()实现继承的方式觉得点问题,就自己研究了一下,所以就有了这篇帖子. 本帖 ...