我在我的應用程序的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