2011-09-04 157 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

统计方法有一个竞争条件:例如,有大量的链接移动,因此在序列中间的路径上的统计将失败。 –