2011-09-04 30 views
13

我試圖使用FSEvents來檢測文件何時添加/從特定文件夾中刪除。目前,我實現了一個圍繞FSEvents的簡單包裝,它工作正常:我得到所有事件。使用Lion上的FSEvents跟蹤文件重命名/刪除

但我現在的問題是,當我在Finder中重命名一個文件時,我捕獲了2個不同的事件:第一個類型爲「重命名」的舊文件名,另一個「重命名」新的文件名。這兩個調用之間的事件id不同。

那麼,我該如何知道哪個「重命名」事件包含舊名稱,哪個事件包含舊名稱?我試着查看文檔,但不幸的是,kFSEventStreamEventFlagItemRenamed沒有記錄......它在Lion中似乎是新的。

PS:我能想到的唯一方法是:在重命名的事件中,我檢查了我的UI,看看是否有與事件路徑對應的項目。如果是這樣,我將其標記爲重命名。如果沒有,我檢查一個項目是否被標記爲重命名,如果是,那麼我將它重命名爲新的事件路徑。但我真的不喜歡這個想法...

編輯:好的,我沿着我的「PS」的一行說了些什麼:我注意到當重命名某些東西時,2個事件的ID是連續的,所以使用包含新名稱的事件的ID,我可以獲取包含舊名稱的事件。在「重命名」事件的情況下,我只是在界面中使用一個小詞典來存儲ID和相關路徑。

反正我現在能趕上重命名事件,甚至是移動事件:當你移動一個文件,這是這是由FSEventStream抓住了「改名」事件......

不過,我還有一個最後問題:刪除。當我刪除某些內容時,它會移至回收站:我收到一個「重命名」事件。但問題是我沒有收到第二次重命名事件。只有.DS_Store文件上的「修改」事件。我想這個文件被Finder用來了解哪些文件在bin中,等等。所以我可以檢查對這個文件的修改,並獲取最後一次「重命名」事件來檢測文件是否被髮送到bin。但是我使用的是使用Apsps的TotalFinder,它修改了Finder存儲.DS_Store文件的方式:我不再在此上收到「修改」。 要sumarize:我無法檢測文件何時發送到垃圾箱...

任何想法我可以做到這一點?也許用FSEvent以外的東西來捕捉這個事件?

回答

13

嗯,我沒有找到完美的答案,我的問題,但我發現了一個解決方案,我最終真的很滿意,所以我想正如我所說的,移動的東西時,我會分享^^

到垃圾箱中,如果您只觀看1個文件夾,則無法捕獲將圖像放入垃圾箱時生成的事件。因此,我決定執行以下操作: 我有一個類在根文件夾(「/」)上創建一個流,以便它可以捕獲所有事件 - >這解決了文件被髮送到垃圾箱的問題,並且所有這些東西。然後,這個班級允許在某些途徑上註冊代表。因此,我不是創建許多流,而是創建一個大流,然後根據需要過濾事件,並創建許多代表。

因此,所有我現在要做的,當我想觀看的特殊文件夾的事件如下:

[[FSEventsListener instance] addListener:self forPath:somePath]; 

我只需要創建在應用程序啓動FSEventListener的實例,而當鬆開應用停止。 而我只需要實現以下3種方法將被自動調用:

-(void)fileWasAdded:(NSString *)file; 
-(void)fileWasRemoved:(NSString *)file; 
-(void)fileWasRenamed:(NSString *)oldFile to:(NSString *)newFile; 

如果你有興趣在這個小工具的源代碼,你可以點擊這裏:http://blog.pcitron.fr/tools/macosx-imageviewer/(實用程序在加入版本0.8)

我開發它作爲一個小圖像查看器的一部分,以保持用戶界面與磁盤內容同步(它顯示包含在每個目錄中的圖像數等)。源代碼可用,實用程序位於Utils/FSEventsListener.h/.m中。

而且萬一有人真的下載應用,並看看源代碼,如果你發現任何有用的(性能/功能的改進,等等)隨時給評論/郵件^^

+0

非常有幫助,感謝您的代碼:) –

+0

在您的網站上沒有聯繫頁面上的發送按鈕,請給我你的電子郵件,我想問你一些問題。謝謝:) –

+0

我在我的網站上修復了聯繫表格。我不知道如何發送私人消息StackOverflow(或者,即使它是可能的^^) – Citron

4

你實際上提出了兩個與FSEvents相關的問題並重新命名。 1.文件被重命名,舊文件名和新文件名均位於被監視的目錄樹中。 2.文件被重命名,其中一個名稱不在被監控的目錄樹中。

你已經解決了(幾乎)第一個問題。還有必要爲您的應用程序提供一種方法,以瞭解在同一FSEvent事件組中報告哪些事件。您知道連續報告兩個重命名的方法僅適用於在同一延遲期內報告的同一組事件。如果類型2的兩個重命名事件一個接一個地發生,但不在同一個延遲組中報告的同一組事件中,那麼它們實際上與對方無關 - 並且您將錯誤地認爲一個文件已被重命名爲另一個。

可以通過簡單地使用根監視系統中的每個目錄來處理第二種重命名類型,但這會使許多不必要的事件氾濫成災。您可以確定「部分」重命名是文件從被監視的目錄樹中移出的結果,還是通過對文件執行stat()操作而進入被監視的目錄樹中的結果。如果stat()失敗且errno爲2,則該文件已被移到受監視的目錄之外,並且可以將其視爲已被刪除。如果stat()成功,則可以將該事件視爲已創建文件。

+0

統計方法有一個競爭條件:例如,有大量的鏈接移動,因此在序列中間的路徑上的統計將失敗。 –