2012-08-06 142 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