2012-07-19 12 views
8

मैक में फ़ोल्डर के लिए मुझे FSEvents वॉचर बनाने की आवश्यकता है। मैं सी ++ के साथ सहज हूं और उद्देश्य-सी के बजाय सी ++ कोड में FSEvents अधिसूचनाएं प्राप्त करने का कोई तरीका है। क्या शुरू करने के लिए कुछ उदाहरण कोड है और मुझे पुस्तकालयों को शामिल करने की आवश्यकता है ..?FSEvents C++ उदाहरण

मैं पहले से ही इस पृष्ठ पर हूं। http://developer.apple.com/library/mac/#featuredarticles/FileSystemEvents/_index.html

लेकिन वहाँ, केवल उद्देश्य सी प्रतीत हो रहा है मैं इसे

उत्तर

13

हाँ, यह सी में संभव है आप कर्नेल कतार के लिए दिखना चाहिए सीपीपी संस्करण हो सकता है।

#include <errno.h>  // for errno 
#include <fcntl.h>  // for O_RDONLY 
#include <stdio.h>  // for fprintf() 
#include <stdlib.h>  // for EXIT_SUCCESS 
#include <string.h>  // for strerror() 
#include <sys/event.h> // for kqueue() etc. 
#include <unistd.h>  // for close() 

int main (int argc, const char *argv[]) 
{ 
    int kq = kqueue(); 
    // dir name is in argv[1], NO checks for errors here 
    int dirfd = open (argv[1], O_RDONLY); 

    struct kevent direvent; 
    EV_SET (&direvent, dirfd, EVFILT_VNODE, EV_ADD | EV_CLEAR | EV_ENABLE, 
      NOTE_WRITE, 0, (void *)dirname); 

    kevent(kq, &direvent, 1, NULL, 0, NULL); 

    // Register interest in SIGINT with the queue. The user data 
    // is NULL, which is how we'll differentiate between 
    // a directory-modification event and a SIGINT-received event. 
    struct kevent sigevent; 
    EV_SET (&sigevent, SIGINT, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, NULL); 
    // kqueue event handling happens after the legacy API, so make 
    // sure it doesn eat the signal before the kqueue can see it. 
    signal (SIGINT, SIG_IGN); 

    // Register the signal event. 
    kevent(kq, &sigevent, 1, NULL, 0, NULL); 

    while (1) { 
     // camp on kevent() until something interesting happens 
     struct kevent change; 
     if (kevent(kq, NULL, 0, &change, 1, NULL) == -1) { exit(1); } 
     // The signal event has NULL in the user data. Check for that first. 
     if (change.udata == NULL) { 
      break; 
     } else { 
     // udata is non-null, so it's the name of the directory 
     printf ("%s\n", (char*)change.udata); 
     } 
    } 
    close (kq); 
    return 0; 
} 

विवरण ch में पाया जा सकता:

यहाँ निर्देशिका को देखने के लिए एक छोटा सा नमूना है। मार्क Dalrymple द्वारा "उन्नत मैक ओएसएक्स प्रोग्रामिंग" के 16 (Kqueues और FSEvents)। अतिरिक्त जानकारी * बीएसडी दस्तावेज में Kqueues के लिए पाया जा सकता है।

या इस एपीआई का उपयोग FSEvents से करें (यह ज्यादातर सी-आधारित है)।

FSEventStreamRef FSEventStreamCreate (CFAllocatorRef allocator, 
            FSEventStreamCallback callback, 
            FSEventStreamContext *context, 
            CFArrayRef pathsToWatch, 
            FSEventStreamEventId sinceWhen, 
            CFTimeInterval latency, 
            FSEventStreamCreateFlags flags); 

शुद्ध सी कॉलबैक साथ FSEvents घटना स्ट्रीम बनाने के लिए। -getCFRunLoop का उपयोग करके किसी NSRunLoop से CFRunLoop मिलती है:

तब का उपयोग कर

void FSEventStreamScheduleWithRunLoop (FSEventStreamRef streamRef, 
            CFRunLoopRef runLoop, 
            CFStringRef runLoopMode); 

हाँ, यहाँ आप शायद Obj सी की एक पंक्ति RunLoop संभाल पाने के लिए इस्तेमाल करना चाहिए अपने runloop को यह घटना धारा देते हैं

CFRunLoop* loopRef = [[NSRunLoop currentRunLoop] getCFRunLoop]; 

या शुद्ध सी कॉल

CFRunLoop* loopRef = CFRunLoopGetCurrent(); 
का उपयोग

ईवेंट प्रारंभ करें

Boolean FSEventStreamStart (FSEventStreamRef streamRef); 

साथ स्ट्रीम इस के साथ runloop से

void FSEventStreamStop (FSEventStreamRef streamRef); 

के साथ घटना धारा बंद करो और फिर यह गैर अनुसूचित:

void FSEventStreamInvalidate (FSEventStreamRef streamRef); 
:

void FSEventStreamUnscheduleFromRunLoop (FSEventStreamRef streamRef, 
            CFRunLoopRef runLoop, 
            CFStringRef runLoopMode); 

धारा (सफाई) अमान्य

आशा है कि यह आपको मिलेगा tarted।

+0

मेरे प्रयोगों में, kqueue कार्यात्मक रूप से FSEvents के बराबर नहीं है। CFRunLoop बिट रूपरेखा के लिए धन्यवाद! – berkus