使用 Grand Central Dispatch 进行文件监控
Posted
技术标签:
【中文标题】使用 Grand Central Dispatch 进行文件监控【英文标题】:File monitoring using Grand Central Dispatch 【发布时间】:2012-07-06 02:38:48 【问题描述】:我正在使用David Hamrick 的代码示例来使用 GCD 监控文件。
int fildes = open("/path/to/config.plist", O_RDONLY);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,fildes,
DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE,
queue);
dispatch_source_set_event_handler(source, ^
//Reload the config file
);
dispatch_source_set_cancel_handler(source, ^
//Handle the cancel
);
dispatch_resume(source);
我想用一个plist来监控一个变化。我在第一次更改后收到通知,但没有收到以下更改的通知。为什么?
【问题讨论】:
【参考方案1】:当收到 DISPATCH_VNODE_DELETE 时,您确实可以重新打开文件并重新注册源(删除前一个源)。或者您可以使用专门为这种场景设计的调用,即 dispatch_io_create_with_path() - 它不仅会按路径观看,还会为您打开文件并让您异步读取内容。
既然你问了(不确定你问的是哪种技术,但这里是最简单的)这里是一个独立的代码示例:
#include <dispatch/dispatch.h>
#include <stdio.h>
int main(int ac, char *av[])
int fdes = open("/tmp/pleasewatchthis", O_RDONLY);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
void (^eventHandler)(void), (^cancelHandler)(void);
unsigned long mask = DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE;
__block dispatch_source_t source;
eventHandler = ^
unsigned long l = dispatch_source_get_data(source);
if (l & DISPATCH_VNODE_DELETE)
printf("watched file deleted! cancelling source\n");
dispatch_source_cancel(source);
else
// handle the file has data case
printf("watched file has data\n");
;
cancelHandler = ^
int fdes = dispatch_source_get_handle(source);
close(fdes);
// Wait for new file to exist.
while ((fdes = open("/tmp/pleasewatchthis", O_RDONLY)) == -1)
sleep(1);
printf("re-opened target file in cancel handler\n");
source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fdes, mask, queue);
dispatch_source_set_event_handler(source, eventHandler);
dispatch_source_set_cancel_handler(source, cancelHandler);
dispatch_resume(source);
;
source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,fdes, mask, queue);
dispatch_source_set_event_handler(source, eventHandler);
dispatch_source_set_cancel_handler(source, cancelHandler);
dispatch_resume(source);
dispatch_main();
【讨论】:
我对 GCD 很陌生,你有使用该代码的示例吗? 正如我在下面所说的,我已经得到了这个解决方案。我说的是 dispatch_io_create_with_path。 参见developer.apple.com/library/ios/#documentation/FileManagement/… - 使用更冗长的通道,对于琐碎的代码 sn-p 来说太冗长了。经过反思,对于您的应用程序(非常简单),我想我会坚持使用嵌套源注册技术。通道适用于更复杂的场景。【参考方案2】:经过一番研究 我发现:
=> 我得到了DISPATCH_VNODE_DELETE
的标志
我正在监视~/Library/Preferences/com.apple.dock.plist
我发现,更改停靠方向,删除原始文件并用新文件替换它。
因此,监控停止。
同一作者提出a solution,在删除的情况下,GCD块调用自身继续监控。
【讨论】:
以上是关于使用 Grand Central Dispatch 进行文件监控的主要内容,如果未能解决你的问题,请参考以下文章
暂停和恢复 Grand Central Dispatch 线程
使用 Grand Central Dispatch (GCD) 创建恰好 N 个线程
NSOperation 与 Grand Central Dispatch
核心数据和线程/ Grand Central Dispatch
使用图层和 Grand Central Dispatch 呈现 UIButton 的最快方法?
iOS 中的 JSON 请求 - 使用 Grand Central Dispatch 或 NSURLConnection