(OS X)确定是否正在写入文件?

时间:2015-01-15 23:12:03

标签: objective-c macos cocoa nsurl nsfilemanager

我的应用正在监控" hot"本地文件系统上某处的文件夹,用于新添加的文件以推送到网络位置。当将非常大的文件写入hot文件夹时,我遇到了问题:在文件完成写入之前,文件系统事件通知我hot文件夹中的更改。当我的应用程序尝试上传文件时,它会错误地将文件大小读取为当前复制的字节数,而不是最终的总字节数。

我尝试的事情:

  • NSURL getResourceValue:forKey:error:阅读NSURLAllocatedFileSizeKey(正在撰写文件时,NSURLFileSizeKey的值相同)。
  • NSFileManager attributesOfItemAtPath:error:查看NSFileBusy(始终为NO)。

我似乎无法找到任何机制,无法重复轮询文件的大小,以确定文件是否已完成复制并可上传。

2 个答案:

答案 0 :(得分:4)

没有很好的方法可以做到这一点。

如果您可以确定作者正在使用NSFileCoordinator,那么您也可以使用它来协调您对该文件的访问。

同样,如果您确定作者已选择加入咨询锁定,则可以尝试使用open()和{{1}调用O_SHLOCK来打开文件以进行共享访问标志。如果您成功,则没有其他描述符可供独占访问。您可以使用您已获得或关闭的文件描述符,然后使用其他API来访问该文件。

但是,如果您无法确定其中任何一项,那么您最好的选择可能是设置计时器以重复检查文件的元数据(大小,修改日期等)。只有当你看到它已经停止在合理的时间间隔(可能是2秒)内改变时,你才会尝试访问它(并取消定时器)。

你可能想要做到这三点。等待文件的元数据稳定下来,然后使用O_NONBLOCK从文件中读取。当它调用您的阅读器块时,请NSFileCoordinatoropen()一起使用,以确保没有其他进程可以独占访问它。

答案 1 :(得分:0)

您需要某种形式的协调文件锁定。

fcntl()和flock()是常见的功能。 先阅读它。 然后看看你有什么选择。 如果您可以控制其他进程的代码库,那就更好了。

真正大文件的问题在于它们内部的变化或变化是不透明的,并不总是在最后。 好的过程通常应该进行原子写入。 (写入临时文件然后将其交换出来)但如果这些文件实际上是数据库,那么您将需要查看使用db的服务器应用程序进行此类操作。

如果文件是包含其他文件的包装器,那么它会变得更加混乱,因为这些内容可能彼此依赖于处于可用状态。