MacOS 开发 - FSEventStream(文件系统改变事件监控)
文章目录
- file system events 的构成
- 核心方法
- Demo 地址
- 使用
- 1、导入 `CoreServices` 框架
- 2、添加属性
- 3、申明 `fsevents_callback` 方法
- 4、实现`fsevents_callback` 方法
- 5、开始监控
- 6、取消监控
- 7、实现私有方法
- 运行结果:
- 参考资料
file system events 的构成
FSEventStream 是一套 C 语言的方法, 类似于 CoreGraphic.
file system events API提供了 文件目录层次改变
的通知(支持10.5以上),该机制(file system events mechanism)由3部分构成:
1、内核传递事件到用户层;
2、一个后台进程过滤事件流,然后发送通知;
3、一个数据库保存这些改变。
开发者注册通知,后台进程发送出了通知以后,就能接收到,然后做相应的处理。
核心方法
- 应用程序通过
FSEventStreamCreate
orFSEventStreamCreateRelativeToDevice
注册、创建一个文件监控句柄。 FSEventStreamScheduleWithRunLoop
使用循环来获取FSEventStreamStart
告诉后台进程开始文件监控FSEventStreamCallback
如果事件产生,然后就回调函数FSEventStreamStop
停止后台进程发送通知FSEventStreamInvalidate
作废事件FSEventStreamRelease
释放事件
Demo 地址
- FSEventStreamDemo 亲测好用
https://github.com/ywwzwb/FSEventStreamDemo
使用
1、导入 CoreServices
框架
import <CoreServices/CoreServices.h>
2、添加属性
@property(nonatomic) NSInteger syncEventID;
@property(nonatomic, assign) FSEventStreamRef syncEventStream;
并加载
#pragma mark - setter
-(void)setSyncEventID:(NSInteger)syncEventID{[[NSUserDefaults standardUserDefaults] setInteger:syncEventID forKey:@"SyncEventID"];
}-(NSInteger)syncEventID {NSInteger syncEventID = [[NSUserDefaults standardUserDefaults] integerForKey:@"SyncEventID"];if(syncEventID == 0) {syncEventID = kFSEventStreamEventIdSinceNow;}return syncEventID;
}
3、申明 fsevents_callback
方法
void fsevents_callback(ConstFSEventStreamRef streamRef,void *userData,size_t numEvents,void *eventPaths,const FSEventStreamEventFlags eventFlags[],const FSEventStreamEventId eventIds[]);
4、实现fsevents_callback
方法
void fsevents_callback(ConstFSEventStreamRef streamRef,void *userData,size_t numEvents,void *eventPaths,const FSEventStreamEventFlags eventFlags[],const FSEventStreamEventId eventIds[]) {ViewController *self = (__bridge ViewController *)userData;NSArray *pathArr = (__bridge NSArray*)eventPaths;FSEventStreamEventId lastRenameEventID = 0;NSString* lastPath = nil;for(int i=0; i<numEvents; i++){FSEventStreamEventFlags flag = eventFlags[i];if(kFSEventStreamEventFlagItemCreated & flag) {NSLog(@"create file: %@", pathArr[i]);}if(kFSEventStreamEventFlagItemRenamed & flag) {FSEventStreamEventId currentEventID = eventIds[i];NSString* currentPath = pathArr[i];if (currentEventID == lastRenameEventID + 1) {// 重命名或者是移动文件NSLog(@"mv %@ %@", lastPath, currentPath);} else {// 其他情况, 例如移动进来一个文件, 移动出去一个文件, 移动文件到回收站if ([[NSFileManager defaultManager] fileExistsAtPath:currentPath]) {// 移动进来一个文件NSLog(@"move in file: %@", currentPath);} else {// 移出一个文件NSLog(@"move out file: %@", currentPath);}}lastRenameEventID = currentEventID;lastPath = currentPath;}if(kFSEventStreamEventFlagItemRemoved & flag) {NSLog(@"remove: %@", pathArr[i]);}if(kFSEventStreamEventFlagItemModified & flag) {NSLog(@"modify: %@", pathArr[i]);}}[self updateEventID];
}
5、开始监控
记得修改你的监控文件夹,你也可以使用代码自动设定文件夹位置
#pragma mark - event
- (IBAction)startWatchClicked:(id)sender {if(self.syncEventStream) {FSEventStreamStop(self.syncEventStream);FSEventStreamInvalidate(self.syncEventStream);FSEventStreamRelease(self.syncEventStream);self.syncEventStream = NULL;}NSArray *paths = @[@"/Users/user/Desktop"];// 这里填入需要监控的文件夹FSEventStreamContext context;context.info = (__bridge void * _Nullable)(self);context.version = 0;context.retain = NULL;context.release = NULL;context.copyDescription = NULL;self.syncEventStream = FSEventStreamCreate(NULL, &fsevents_callback, &context, (__bridge CFArrayRef _Nonnull)(paths), self.syncEventID, 1, kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagUseCFTypes);FSEventStreamScheduleWithRunLoop(self.syncEventStream, CFRunLoopGetMain(), kCFRunLoopDefaultMode);FSEventStreamStart(self.syncEventStream);}
6、取消监控
- (IBAction)stopWatchClicked:(id)sender {if(self.syncEventStream) {FSEventStreamStop(self.syncEventStream);FSEventStreamInvalidate(self.syncEventStream);FSEventStreamRelease(self.syncEventStream);self.syncEventStream = NULL;}
}
7、实现私有方法
#pragma mark - private method
-(void)updateEventID {self.syncEventID = FSEventStreamGetLatestEventId(self.syncEventStream);
}
运行结果:
在桌面创建一个文件夹,并把文件夹改名为 123
后,打印结果如下:
22:06:01.976 - create file: /Users/user/Desktop/未命名文件夹22:06:01.976 - modify: /Users/user/Desktop/.DS_Store22:06:05.203 - create file: /Users/user/Desktop/未命名文件夹22:06:05.203 - move out file: /Users/user/Desktop/未命名文件夹22:06:05.203 - mv /Users/user/Desktop/未命名文件夹 /Users/user/Desktop/12322:06:08.581 - modify: /Users/user/Desktop/.DS_Store
参考资料
yww:使用 FSEventStream 监控 Mac 文件变化
http://www.jianshu.com/p/7c37b39b143eAlexJing_WU:watch File System Events(文件系统改变事件监控)
http://blog.csdn.net/u012972257/article/details/17302985
MacOS 开发 - FSEventStream(文件系统改变事件监控)相关推荐
- linux流行开源监控框架,Inotify: 高效、实时的Linux文件系统事件监控框架
概要 - 为什么需要监控文件系统? 在日常工作中,人们往往需要知道在某些文件(夹)上都有那些变化,比如: 通知配置文件的改变 跟踪某些关键的系统文件的变化 监控某个分区磁盘的整体使用情况 系统崩溃时进 ...
- inotify之文件系统事件监控使用入门
inotify是linux文件系统事件监控机制,功能强大,控制简单,可以实现很多有用的功能.如:当一个文件被访问.打开.关闭.移动.删除等等时做一些处理.此功能需要内核支持,从kernel 2.6.1 ...
- linux 高效的文件系统事件监控 内核级解析方案 inotify
转载 http://www.lvtao.net/config/inotify.html linux 高效的文件系统事件监控 内核级解析方案 inotify 安装inotify-tools (http: ...
- inotify 实时的Linux文件系统事件监控
标签:inotifywait 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://cqfish.blog.51cto.com/6222 ...
- 如何方便的让你的集合引发改变事件
在我们开发自定义控件的过程中,我们常常会给控件添加集合属性.比如定制Grid控件就会有Column集合.当集合属性发生变化时,比如添加新元素,删除新元素,我们要通知控件去重绘以反映新的变化.我们可以创 ...
- WINDOWS键盘事件监控原理及应用 (转)
WINDOWS键盘事件监控原理及应用 (转)[@more@]windows键盘事件监控原理及应用 赵桂华 ·逸仙时空 WINDOW的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种 ...
- Spring项目接入微信关注/取消关注事件监控(含代码demo,自动回复图文)
微信官方文档地址:关注/取消关注事件 | 微信开放文档 以上,文档提到:用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL,接下来我们就来看看这个URL怎么配置. [配置步骤]: ...
- macos 开发工具_10个面向高级用户和开发人员的必备macOS工具
macos 开发工具 重点 (Top highlight) Macs are expensive machines primarily used by power users and develope ...
- inotify事件监控
一.原理: inotify事件监控,可以监控文件系统中添加,删除,修改,移动等各种事件,一旦发现数据彼此不同,会通知rsync同步推送数据.inotify + rsync可以时时同步 二.准备工作 1 ...
最新文章
- [转]url传递中文的解决方案总结
- html5常见面试题,HTML5常见面试题及答案
- 不错php文件缓存类,一个不错的PHP文件页面缓存类
- Asp.net 安装包制作 (转)
- Xamarin.Forms客户端第一版
- JAVA netty 定时任务_Netty HashedWheelTimer 定时任务调用
- MVP公益活动:编程一小时
- 算法笔记_172:历届试题 波动数列(Java)
- 输出101到200的素数python_python 判断101-200之间有多少个素数,并输出所有素数。...
- WSO2 ESB 5.0.0 最低高可用性部署
- 飞塔(FortiGate)配置IPSec
- HTML谷歌怎么加背景音乐,谷歌Chrome浏览器怎么提取网页的背景音乐?
- Udesk即时通讯网页插件发送咨询对象(一、使用内嵌代码)
- php vip卡,vip.php
- 如何批量修改文件夹中的照片名称
- JSON格式字符串解析,转换为JSONObject
- Stream代替for循环
- CentOS7虚拟机取消屏幕保护
- 计算机两短 解决,电脑主机老一声长响伴两声短响后开不了机是怎
- 使用 MyBatis 实体类里的 Double 类型查询不到值
热门文章
- ​力扣解法汇总790. 多米诺和托米诺平铺
- 第04章 逻辑架构【1.MySQL架构篇】【MySQL高级】
- linux添加硬盘配置内核pci,Linux系统入门学习:在虚拟机上配置PCI直通
- 计算机组成原理 - 存储器
- Python利用igraph绘制复杂网络聚类(社区检测)结果图
- 201671010411.巩定定 实验三.作业互评与改进
- 【编辑】VMware安装没有引导的Ghost镜像win10
- C# 根据日期计算星期几
- postgresql 序列Sequence
- 机器学习 | MATLAB实现MLP多层感知机模型设计