2012-11-13 81 views
1

我試圖製作一個應用程序,它僅監視特定文件夾的更改並輸出更改文件的路徑。它稍後將對這些更改的文件進行一些處理。我會如何去做這個在本土可可?我嘗試過的東西列在: http://developer.apple.com/library/mac/#featuredarticles/FileSystemEvents/_index.html監視特定文件夾的更改並檢測哪些文件在Cocoa中發生了更改

但我無法弄清楚如何有效地完成任務。

代碼示例將不勝感激。

+0

這將會是有用的,如果你已經嘗試和失敗,你可以在更具體。 – vicvicvic

回答

0

這個例子是做你想做的事的基本方法。

看看Using the FSEvents Framework文件。它告訴你所有你需要啓動和運行。我在這裏給出的代碼示例與文檔中列出的相同。

3

看一看fs-notifier通過Peter Hosey

@interface Notifier : NSObject { 
    NSArray *paths; //Actually just one. 
    FSEventStreamRef stream; 
    struct FSEventStreamContext context; 
} 

+ (id) notifierWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath; 
- (id) initWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath; 

- (void) start; 
- (void) stop; 

@end 
#import "Notifier.h" 

@implementation Notifier 

+ (id) notifierWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath { 
    return [[[self alloc] initWithCallback:newCallback path:newPath] autorelease]; 
} 
- (id) initWithCallback:(FSEventStreamCallback)newCallback path:(NSString *)newPath { 
    if((self = [super init])) { 
     paths = [[NSArray arrayWithObject:newPath] retain]; 
     context.version = 0L; 
     context.info = newPath; 
     context.retain = (CFAllocatorRetainCallBack)CFRetain; 
     context.release = (CFAllocatorReleaseCallBack)CFRelease; 
     context.copyDescription = (CFAllocatorCopyDescriptionCallBack)CFCopyDescription; 

     stream = FSEventStreamCreate(kCFAllocatorDefault, newCallback, &context, (CFArrayRef)paths, kFSEventStreamEventIdSinceNow, /*latency*/ 1.0, kFSEventStreamCreateFlagUseCFTypes); 
     if (!stream) { 
      NSLog(@"Could not create event stream for path %@", newPath); 
      [self release]; 
      return nil; 
     } 

     FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 
    } 
    return self; 
} 

- (void) dealloc { 
    [self stop]; 
    FSEventStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 
    CFRelease(stream); 
    [super dealloc]; 
} 

- (void) start { 
    FSEventStreamStart(stream); 
} 
- (void) stop { 
    FSEventStreamStop(stream); 
} 

@end 

#import "Notifier.h" 

static void gotEvent(ConstFSEventStreamRef streamRef, 
        void *clientCallBackInfo, 
        size_t numEvents, 
        void *eventPaths, 
        const FSEventStreamEventFlags eventFlags[], 
        const FSEventStreamEventId eventIds[]); 

int main (int argc, char **argv) { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSArray *paths = [[NSProcessInfo processInfo] arguments]; 

    NSMutableArray *streams = [NSMutableArray arrayWithCapacity:[paths count]]; 
    for (NSString *path in paths) { 
     [streams addObject:[Notifier notifierWithCallback:gotEvent path:path]]; 
    } 

    [streams makeObjectsPerformSelector:@selector(start)]; 
    CFRunLoopRun(); 

    [pool drain]; 
    return EXIT_SUCCESS; 
} 

static void gotEvent(ConstFSEventStreamRef stream, 
        void *clientCallBackInfo, 
        size_t numEvents, 
        void *eventPathsVoidPointer, 
        const FSEventStreamEventFlags eventFlags[], 
        const FSEventStreamEventId eventIds[] 
) { 
    NSArray *eventPaths = eventPathsVoidPointer; 
    NSString *streamName = clientCallBackInfo; 
    NSLog(@"%@: %@", streamName, [eventPaths objectAtIndex:0UL]); 
}