2011-10-13 11 views
11

Niedawno zmieniłem z użycia kqueue na GCD dispatch sources, aby monitorować zmiany w plikach. To zadziałało dobrze i zaowocowało znacznie prostszym API. Udokumentowałem mój przełącznik here. Jedyny problem jaki mam to to, że teraz nie mogę uzyskać dostępu do flag na wydarzeniu, które udało mi się zrobić w kasynie. Na przykład z KQUEUE byłem w stanie sprawdzić, czy plik został usunięty, przemianowany lub jest to atrybuty zostały zmienione z następujących czynności:Flagi źródła wysyłania Grand Central Dispatch (GCD)

struct kevent event; 

... 

if(event.flag & EV_DELETE) 
{ 
    printf("File was deleted\n"); 
} 

Jest to API niedostępne z GCD czy trzeba skonfigurować źródła wysyłkowe górę dla każdej flagi chciałbym słuchać. A może najlepiej użyć kqueue, ponieważ zapewnia on lepszą widoczność zdarzenia, które miało miejsce.

+3

Tak naprawdę nie przeczytałem twojego pytania, ale udało mi się je przeczytać, więc twoja reputacja może być 1337. OK, przeczytam to teraz. – morningstar

Odpowiedz

8

Znalazłem odpowiedź w Concurrency Programming Guide. Najpierw zaglądałem do GCD Reference, ale bez powodzenia. Odpowiednia linia z przewodnika to:

Dla źródła wysyłki deskryptora, które monitoruje działanie systemu plików, ta funkcja zwraca stałą wskazującą typ zdarzenia, które miało miejsce. Lista stałych znajduje się w wyliczeniu typu dispatch_source_vnode_flags_t.

Oto przykład, jak z niego korzystać.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
int fildes = open("path/to/some/file", O_EVTONLY); 
__block 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,^
{ 
    unsigned long flags = dispatch_source_get_mask(source); 
    if(flags & DISPATCH_VNODE_DELETE) 
     printf("DISPATCH_VNODE_DELETE\n"); 
    if(flags & DISPATCH_VNODE_WRITE) 
     printf("DISPATCH_VNODE_WRITE\n"); 
    if(flags & DISPATCH_VNODE_EXTEND) 
     printf("DISPATCH_VNODE_EXTEND\n"); 
    if(flags & DISPATCH_VNODE_ATTRIB) 
     printf("DISPATCH_VNODE_ATTRIB\n"); 
    if(flags & DISPATCH_VNODE_LINK) 
     printf("DISPATCH_VNODE_LINK\n"); 
    if(flags & DISPATCH_VNODE_RENAME) 
     printf("DISPATCH_VNODE_RENAME\n"); 
    if(flags & DISPATCH_VNODE_REVOKE) 
     printf("DISPATCH_VNODE_REVOKE\n"); 
}); 
dispatch_source_set_cancel_handler(source, ^(void) 
{ 
    close(fildes); 
}); 
dispatch_resume(source); 
+0

Dziękuję, to niesamowite. Użyłem tego na [post na blogu] (http://www.davidhamrick.com/2011/10/13/Monitoring-Files-With-GCD-Being-Edited-Wa---Text-Editor.html). Powinieneś jednak poprawić linię 17 z '[blockSelf watchStyleSheet: path];' to '[blockSelf watchConfigFile: path];'. –

+0

nie ma sensu, aby 'source' było' __block', ponieważ nigdy nie jest przypisane do – user102008

3

można zmienić * dispatch_source_get_mask (źródło) * do * dispatch_source_get_data (źródło) *, jak dispatch_source_get_mask (źródło) zwraca wszystkie flagi zdałeś w tworzeniu przewodnika zamiast zdarzenia wygenerowane.

Powiązane problemy