我正在尝试创建一个只监视特定文件夹以进行更改的应用程序,并输出已更改文件的路径。稍后它将对这些已更改的文件进行一些处理。我如何在原生可可中做到这一点?我尝试过以下列出的事情: http://developer.apple.com/library/mac/#featuredarticles/FileSystemEvents/_index.html
但我无法弄清楚如何有效地完成任务。
非常感谢代码示例。
答案 0 :(得分:3)
@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]);
}
答案 1 :(得分:0)
示例是做你想做的事情的基本方法。
查看Using the FSEvents Framework文档。它告诉您启动和运行所需的一切。我在这里给出的代码示例与文档中列出的相同。