天天看點

建立DISPATCH_SOURCE_TYPE_VNODE派發源

如果需要監控檔案系統對象的變化,可以設定一個 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;

}