文章目录

  • 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 or FSEventStreamCreateRelativeToDevice 注册、创建一个文件监控句柄。
  • 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/7c37b39b143e

  • AlexJing_WU:watch File System Events(文件系统改变事件监控)
    http://blog.csdn.net/u012972257/article/details/17302985

MacOS 开发 - FSEventStream(文件系统改变事件监控)相关推荐

  1. linux流行开源监控框架,Inotify: 高效、实时的Linux文件系统事件监控框架

    概要 - 为什么需要监控文件系统? 在日常工作中,人们往往需要知道在某些文件(夹)上都有那些变化,比如: 通知配置文件的改变 跟踪某些关键的系统文件的变化 监控某个分区磁盘的整体使用情况 系统崩溃时进 ...

  2. inotify之文件系统事件监控使用入门

    inotify是linux文件系统事件监控机制,功能强大,控制简单,可以实现很多有用的功能.如:当一个文件被访问.打开.关闭.移动.删除等等时做一些处理.此功能需要内核支持,从kernel 2.6.1 ...

  3. linux 高效的文件系统事件监控 内核级解析方案 inotify

    转载 http://www.lvtao.net/config/inotify.html linux 高效的文件系统事件监控 内核级解析方案 inotify 安装inotify-tools (http: ...

  4. inotify 实时的Linux文件系统事件监控

    标签:inotifywait 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://cqfish.blog.51cto.com/6222 ...

  5. 如何方便的让你的集合引发改变事件

    在我们开发自定义控件的过程中,我们常常会给控件添加集合属性.比如定制Grid控件就会有Column集合.当集合属性发生变化时,比如添加新元素,删除新元素,我们要通知控件去重绘以反映新的变化.我们可以创 ...

  6. WINDOWS键盘事件监控原理及应用 (转)

    WINDOWS键盘事件监控原理及应用 (转)[@more@]windows键盘事件监控原理及应用 赵桂华 ·逸仙时空 WINDOW的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种 ...

  7. Spring项目接入微信关注/取消关注事件监控(含代码demo,自动回复图文)

    微信官方文档地址:关注/取消关注事件 | 微信开放文档 以上,文档提到:用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL,接下来我们就来看看这个URL怎么配置. [配置步骤]: ...

  8. macos 开发工具_10个面向高级用户和开发人员的必备macOS工具

    macos 开发工具 重点 (Top highlight) Macs are expensive machines primarily used by power users and develope ...

  9. inotify事件监控

    一.原理: inotify事件监控,可以监控文件系统中添加,删除,修改,移动等各种事件,一旦发现数据彼此不同,会通知rsync同步推送数据.inotify + rsync可以时时同步 二.准备工作 1 ...

最新文章

  1. [转]url传递中文的解决方案总结
  2. html5常见面试题,HTML5常见面试题及答案
  3. 不错php文件缓存类,一个不错的PHP文件页面缓存类
  4. Asp.net 安装包制作 (转)
  5. Xamarin.Forms客户端第一版
  6. JAVA netty 定时任务_Netty HashedWheelTimer 定时任务调用
  7. MVP公益活动:编程一小时
  8. 算法笔记_172:历届试题 波动数列(Java)
  9. 输出101到200的素数python_python 判断101-200之间有多少个素数,并输出所有素数。...
  10. WSO2 ESB 5.0.0 最低高可用性部署
  11. 飞塔(FortiGate)配置IPSec
  12. HTML谷歌怎么加背景音乐,谷歌Chrome浏览器怎么提取网页的背景音乐?
  13. Udesk即时通讯网页插件发送咨询对象(一、使用内嵌代码)
  14. php vip卡,vip.php
  15. 如何批量修改文件夹中的照片名称
  16. JSON格式字符串解析,转换为JSONObject
  17. Stream代替for循环
  18. CentOS7虚拟机取消屏幕保护
  19. 计算机两短 解决,电脑主机老一声长响伴两声短响后开不了机是怎
  20. 使用 MyBatis 实体类里的 Double 类型查询不到值

热门文章

  1. ​力扣解法汇总790. 多米诺和托米诺平铺
  2. 第04章 逻辑架构【1.MySQL架构篇】【MySQL高级】
  3. linux添加硬盘配置内核pci,Linux系统入门学习:在虚拟机上配置PCI直通
  4. 计算机组成原理 - 存储器
  5. Python利用igraph绘制复杂网络聚类(社区检测)结果图
  6. 201671010411.巩定定 实验三.作业互评与改进
  7. 【编辑】VMware安装没有引导的Ghost镜像win10
  8. C# 根据日期计算星期几
  9. postgresql 序列Sequence
  10. 机器学习 | MATLAB实现MLP多层感知机模型设计