如果需要監控檔案系統對象的變化,可以設定一個 DISPATCH_SOURCE_TYPE_VNODE 類型的dispatch source,你可以從這個dispatch source中接收檔案删除、寫入、重命名等通知。你還可以得到檔案的特定中繼資料資訊變化通知和 文檔目錄中檔案的變動通知。在dispatch source正在處理事件時,dispatch source中指定的檔案描述符必須保持打開狀态。下面例子監控一個檔案的檔案名變化,并在檔案名變化時執行一些操作。由于檔案描述符專門為dispatch source打開,dispatch source安裝了取消處理器來關閉檔案描述符。這個例子中的檔案描述符關聯到底層的檔案系統對象,是以同一個dispatch source可以用來檢測多次檔案名變化。
dispatch_source_t monitorNameChangesToFile(const char* filename)
{
int fd = open(filename, O_EVTONLY);
if (fd == -1)
return NULL;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,
fd, DISPATCH_VNODE_RENAME, queue);
if (source)
{
// Copy the filename for later use.
int length = strlen(filename);
char* newString = (char*)malloc(length + 1);
newString = strcpy(newString, filename);
dispatch_set_context(source, newString);
// Install the event handler to process the name change
dispatch_source_set_event_handler(source, ^{
const char* oldFilename = (char*)dispatch_get_context(source);
NSLog(@"檔案名被改");
});
// Install a cancellation handler to free the descriptor
// and the stored string.
dispatch_source_set_cancel_handler(source, ^{
char* fileStr = (char*)dispatch_get_context(source);
free(fileStr);
close(fd);
});
// Start processing events.
dispatch_resume(source);
}
else
close(fd);
return source;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"==========檔案系統對象派發源===========");
monitorNameChangesToFile("/Users/feinno/Desktop/test");
[[NSRunLoop currentRunLoop]run];
}
return 0;
}