I am writing an application that saves data into a set of text files inside a specific folder.
And I have an FSEventStream
to be notified when other apps (like Dropbox or TextEdit) alter files, so I can update my application with the new text content provided.
The problem is that with my FSEventStream
- despite I set a kFSEventStreamCreateFlagIgnoreSelf
flag - I receive notifications even when modifying files within my own application.
This brings a lot of complications, because after I save the file and get the file-change notification, I have to re-check the file. We can talk about optimisation here, but with my structure of data it is a lot of unnecessary operations and disk usage.
The question is: How can I separate the a) File-events from other applications from b) File-events generated with my own application?
I thought there might be a way to get the processID by the FSEventID (the latter is provided in a callback function). But didn't find anything about it. And it looks like the EventID is provided only to define the order in chain of FileEvents.
What I want is to ignore self-generated FileSystem events.
Here is the code I use to setup the FSEventStream:
NSArray * pathArray = [NSArray arrayWithObject:_pathToObserve];
FSEventStreamContext context;
context.info = self;
context.version = 0;
context.retain = NULL;
context.release = NULL;
context.copyDescription = NULL;
_fsEventStream = FSEventStreamCreate(NULL,
filesystemObserverCallback,
&context,
(CFArrayRef)pathArray,
kFSEventStreamEventIdSinceNow,
1.0,
kFSEventStreamCreateFlagIgnoreSelf|kFSEventStreamCreateFlagFileEvents|kFSEventStreamCreateFlagUseCFTypes);
FSEventStreamScheduleWithRunLoop(_fsEventStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(_fsEventStream);
And the callback function:
void filesystemObserverCallback(ConstFSEventStreamRef streamRef,
void * clientCallBackInfo,
size_t numEvents,
void * eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
NSArray * pathArray = (NSArray *)eventPaths;
for (int i=0; i < numEvents; i++)
{
NSString * path = [pathArray objectAtIndex:i];
FSEventStreamEventFlags flags = flagsArray[i];
if (flags & kFSEventStreamEventFlagItemCreated ||
flags & kFSEventStreamEventFlagItemRemoved ||
flags & kFSEventStreamEventFlagItemRenamed ||
flags & kFSEventStreamEventFlagItemFinderInfoMod ||
flags & kFSEventStreamEventFlagItemChangeOwner ||
flags & kFSEventStreamEventFlagItemXattrMod)
{
NSLog(@">> item has changed at path: %@", path);
}
}
}