2012-08-06 37 views
1

我有一些代码检查文件是否存在,如果存在,则删除它。问题是,即使文件不可写入,我也无法使其失败。我的代码看起来像:NSFileManager removeItemAtPath:错误:不尊重POSIX权限

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; 
     } 
    } 

即使我设置所有权根:车轮和模式000(即不可读的,由任何人可写或可执行文件)的文件仍默默地删除。我从中运行该帐户是一个具有管理员权限的用户帐户,但即使如此,能够杀死root拥有的文件似乎并不安全。抛出错误的唯一方法是使用chflags uchg文件名来锁定文件。我还实施了(作为现在的存根)fileManager:shouldRemoveItemAtPath:委托方法,我可以在必要时检查权限。问题是,从这种方法返回NO不会导致removeItemAtPath:返回一个错误。用fileExistsAtPath:重新检查似乎很麻烦。最后,似乎没有一种简单的方法来区分在委托方法中哪个NSFileManager实例正在向removeItemAtPath:发出呼叫。通常情况下,这些实例是暂时性对象,因此它们的ID在任何相当长的时间内都无效。我可以分类NSFileManager并添加一个标记实例变量,但似乎像一个大锤打击坚果。

总结:

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

2)在委托方法不允许文件删除不传送回的removeItemAtPath

3)确定哪些调用被调用委托方法呼叫者是硬

+1

这听起来像标准的POSIX行为。尝试相同的操作,但不是使用'NSFileManager',而是在命令行使用'rm'。您仍然可以删除该文件。 – 2012-08-06 07:10:40

+0

是的,我只是不确定Cocoa文件管理函数在多大程度上充当了POSIX文件系统调用的包装。我想最后'removeFileAtPath:'调用'unlink(2)'。我仍然不确定如何处理委托和调用者之间的通信。现在我正在继承'NSFileManager'。 – 2012-08-06 15:05:48

回答

4

这是正确的行为。擦除文件不需要对文件的读取访问权限,只需要包含它的目录。将目录看作文件列表,并将文件擦除为简单地从列表中删除,这都是有道理的。

+0

我知道这是标准的UNIX行为(并且我从来没有喜欢过),但它让我觉得有点'un-Mac-like'。 – 2012-08-06 15:07:31