我在应用程序的Documents目录上有一个kQueue观察者。我使用的是在文档目录内容更改时触发回调的kQueue。
以下是其中两个设置
eventToAdd.flags = EV_ADD | EV_CLEAR;
eventToAdd.fflags = NOTE_WRITE;问题是,当添加新文件时,当内容发生更改时,我会收到通知,但实际的文件尚未完全复制,因此当我尝试处理新文件时,我得到了SIGABRT崩溃。
如何延迟通知,直到文件完成?
发布于 2013-03-14 05:38:10
我通过创建2个监听器解决了这个问题...一个位于应用程序的文档目录中,用于监视出现的新文件;另一个是为出现的每个文件创建的文件代理对象。文件对象有一个fileBusy标志。file对象在将数据块写入文件时设置2秒计时器。如果在计时器到期之前没有更新,我假设文件已经完全写入。
文件更改监听器代码如下:https://gist.github.com/nielsbot/5155671
下面是上面的监听器的(部分)委托。(代表磁盘上文件的" file“对象)
@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发布于 2013-03-14 03:41:20
首先,请参阅:
简短的答案是,没有很好的方法来做到这一点。理想情况下,您应该将文件写入其他位置,然后将其移动到文档中。这使得它成为一个原子动作。或者将其写为一个特殊的文件名(".partial“、".download”等),并在末尾重命名(同样,将触发第二个kqueue事件的原子操作)。
https://stackoverflow.com/questions/15285966
复制相似问题