KQueue Directory Monitoring

I have a kQueue observer in the Documents directory in my application. I use kQueue, which calls a callback when the contents of the document directory change.

here are two of the settings

eventToAdd.flags = EV_ADD | EV_CLEAR; eventToAdd.fflags = NOTE_WRITE; 

The problem is that I get a notification when the content changes when a new file is added, but the actual file is not fully copied yet, so when I try to process a new file, I get a SIGABRT failure.

How can I delay the notification until the file is completed?

+4
source share
2 answers

I solved this by creating 2 listeners ... one in the application’s document directory for viewing new files and a proxy file object that is created for each displayed file. The File object has the fileBusy flag. The File object sets a 2-second timer when a piece of data is written to the file. I assume that the file is completely written if there are no updates before the timer expires.

File change listener code here: https://gist.github.com/nielsbot/5155671

My (incomplete) delegate for the above listener is below. (File object representing a file on disk)

 @implementation File<FileChangeObserverDelegate> -(void)scheduleFileBusyTimeout { self.fileBusyTimeoutTimer = [ NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector( fileBusyTimeoutTimerFired: ) userInfo:nil repeats:NO ] ; } -(void)setFileChangeObserver:(FileChangeObserver *)observer { [_fileChangeObserver invalidate ] ; _fileChangeObserver = observer ; } -(void)fileChanged:(FileChangeObserver *)asset typeMask:(enum FileChangeNotificationType)type { @synchronized( self ) { if ( ( type & kFileChangeType_Delete ) != 0 ) { // we're going away soon... self.fileChangeObserver = nil ; } else { self.fileBusy = YES ; [ self scheduleFileBusyTimeout ] ; } } } -(void)fileBusyTimeoutTimerFired:(NSTimer*)timer { @autoreleasepool { self.fileBusy = NO ; } } -(void)setFileBusyTimeoutTimer:(NSTimer *)timer { [ _fileBusyTimeoutTimer invalidate ] ; _fileBusyTimeoutTimer = timer ; } @end 
+2
source

First, see

Short answer: there is no great way to do this. Ideally, you should write the file elsewhere and then move it to Documents. This makes it an atomic action. Or write it as a special file name (".partial", ".download", etc.) and rename it at the end (again, the atomic action that will fire the second kqueue event).

0
source

All Articles