NSFileManager removeItemAtPath:error: 不尊重 POSIX 权限

Posted

技术标签:

【中文标题】NSFileManager removeItemAtPath:error: 不尊重 POSIX 权限【英文标题】:NSFileManager removeItemAtPath:error: does not respect POSIX permissions 【发布时间】:2012-08-06 00:04:36 【问题描述】:

我有一些代码可以检查文件是否存在,如果存在,则将其删除。问题是,即使文件不可写,我也无法让它失败。我的代码如下:

if([theManager fileExistsAtPath:savingAs isDirectory:&destIsDir])
   
   BOOL itemRemoved=[theManager removeItemAtPath:savingAs error:&err];
   if(!itemRemoved)
      
      // why?
      NSAlert *rebuildAlert=[NSAlert alertWithMessageText:@"Error removing item" 
        defaultButton:nil alternateButton:nil otherButton:nil
        informativeTextWithFormat:@"%@",[err localizedDescription]];
      [rebuildAlert runModal];
      proceed=NO;
      
   

即使我将所有权设置为 root:wheel 并将模式设置为 000(即任何人都不可读取、不可写入或可执行),该文件仍会被静默删除。我运行它的帐户是具有管理员权限的用户帐户,但即便如此,能够杀死 root 拥有的文件似乎也不是很安全。抛出错误的唯一方法是使用chflags uchg filename 锁定文件。我还实现了(现在作为存根)fileManager:shouldRemoveItemAtPath: 委托方法,如果需要,我可以在其中检查权限。问题是从此方法返回NO 不会导致removeItemAtPath: 返回错误。用fileExistsAtPath: 重新检查似乎很麻烦。最后,似乎没有一个简单的方法来消除NSFileManager 的哪个实例在委托方法中发出对removeItemAtPath: 的调用。通常,这些实例是临时对象,因此它们的 id 在任何重要的时间长度内都无效。我可以继承 NSFileManager 并添加一个标签实例变量,但这似乎是一把大锤来破解坚果。

总结:

1) removeItemAtPath 忽略不属于它的文件的行为是否正确?

2) 在委托方法中不允许删除文件不会传回给removeItemAtPath的调用者

3) 很难确定哪个调用正在调用委托方法

【问题讨论】:

这听起来像是标准的 POSIX 行为。尝试相同的操作,但不要使用NSFileManager,而是在命令行中使用rm。您仍然可以删除该文件。 是的,我只是不确定 Cocoa 文件管理功能在多大程度上充当了 POSIX 文件系统调用的包装器。我猜最后removeFileAtPath: 调用unlink(2)。我仍然不确定如何处理代表和调用者之间的通信。现在我正在继承NSFileManager 【参考方案1】:

这是正确的行为。擦除文件不需要读取文件,只需要包含它的目录。将目录视为文件列表,将文件删除视为简单地将其从该列表中删除,这一切都有意义。

【讨论】:

我知道这是标准的 UNIX 行为(而且我从来都不喜欢这种行为),但它让我觉得有点“不像 Mac”。

以上是关于NSFileManager removeItemAtPath:error: 不尊重 POSIX 权限的主要内容,如果未能解决你的问题,请参考以下文章

NSFilemanager 的使用

NSFileManager

NSFileManager的应用

教程 使用 NSFileManager 存储数据?

NSFileManager和NSFileHandle

NSFileManager - 创建一个只读文件