我在我的应用程序的Documents目录上有一个kQueue观察者。我正在使用在文档目录内容更改时触发回调的kQueue。kQueue目录监控
这里有两个设置
eventToAdd.flags = EV_ADD | EV_CLEAR;
eventToAdd.fflags = NOTE_WRITE;
的问题是,我得到通知,当内容发生变化时增加了一个新的文件,但实际的文件还没有完全复制,所以当我尝试的过程新文件我得到一个SIGABRT崩溃。
如何推迟通知,直到文件完成?
我在我的应用程序的Documents目录上有一个kQueue观察者。我正在使用在文档目录内容更改时触发回调的kQueue。kQueue目录监控
这里有两个设置
eventToAdd.flags = EV_ADD | EV_CLEAR;
eventToAdd.fflags = NOTE_WRITE;
的问题是,我得到通知,当内容发生变化时增加了一个新的文件,但实际的文件还没有完全复制,所以当我尝试的过程新文件我得到一个SIGABRT崩溃。
如何推迟通知,直到文件完成?
我解决了这个问题,方法是创建两个监听器...一个在应用程序的Documents目录中以监视新文件的出现以及为每个出现的文件创建的File代理对象。 File对象有一个fileBusy
标志。当大块数据写入文件时,File对象设置2秒计时器。如果在定时器到期之前没有更新,我认为文件是完全写入的。
文件更改监听器代码在这里:https://gist.github.com/nielsbot/5155671
我的(部分)委托低于上述监听器。 (表示文件在磁盘上的“文件”对象)
@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
首先,请参阅:
简短的回答是,没有很好的方法来做到这一点。理想情况下,您应该将文件写入其他位置,然后将其移至文档中。这使其成为原子行动。或者把它写成一个特殊的文件名(“.partial”,“.download”等),并在最后重命名(同样是一个会触发第二个kqueue事件的原子动作)。
我喜欢'.partial'概念 - 尽管如果你通过iTunes放入文件,它不会遵守这个规则。我的解决方法是在每次写入文件后设置一个计时器,然后假定该文件在1秒左右后完全写入。 – nielsbot 2013-03-13 20:16:36
@nielsbot - 是1秒左右吗?添加文件名时是否触发事件,并且根据文件大小,写操作是动态的,并且定时不可知。 – jarryd 2013-03-13 21:02:07
每次将_new chunk_写入文件时,您将收到一条kqueue通知 - 在每个chunk_之后将您的计时器重置为1秒。 1s计时器不适用于整个文件写入。如果没有组块被写入1s的持续时间,假定文件被完全写入。我不明白,但我知道,但我想不出更好的办法。 – nielsbot 2013-03-13 21:30:45
谢谢你。我会尽快尝试并回复你。 – jarryd 2013-03-13 22:15:11