2014-12-03 94 views
3

我正面臨着這個奇怪的問題。 刪除文件unlink()在我的代碼中調用API。此調用刪除文件並在非Windows平臺上成功。在Windows上它成功(返回0),但不會刪除該文件。DeleteFile()或unlink()調用成功,但不會刪除文件

爲了實驗,我添加了一個循環來重複調用相同的API。在第二次迭代中,我得到了Permission denied錯誤,錯誤代碼= 13。雖然讀/寫屬性設置爲文件,程序具有完全訪問文件的權限。

然後我調用DeleteFile()而不是unlink()API。令我驚訝的是,我看到了相同的結果,調用成功,即返回1,但文件沒有被物理刪除。

我通過解鎖程序實用程序進行檢查,沒有其他程序正在訪問除試圖刪除此文件的程序的文件。

有沒有人知道還有什麼可能是錯的?

編輯1: 只是爲了確保文件在刪除時未打開。我在創建文件時保存了句柄,並在刪除文件之前試圖關閉該句柄,但出現錯誤「'UNOPENED'(Errcode:9 - Bad file descriptor)」。因此,我認爲該文件在刪除時未打開。

編輯2 根據要求,以下是用於創建和刪除文件的代碼的簡化版本。

// Code to create the file 
int create_file(const char* path) 
{ 
    HANDLE osfh;       /* OS handle of opened file */ 
    DWORD fileaccess;      /* OS file access (requested) */ 
    DWORD fileshare;      /* OS file sharing mode */ 
    DWORD filecreate;      /* OS method of opening/creating */ 
    DWORD fileattrib;      /* OS file attribute flags */ 
    SECURITY_ATTRIBUTES SecurityAttributes; 


    SecurityAttributes.nLength= sizeof(SecurityAttributes); 
    SecurityAttributes.lpSecurityDescriptor= NULL; 
    SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT); 



fileaccess= GENERIC_WRITE; 
fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 
filecreate= CREATE_NEW; 


if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, 
filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) 
{ 
    // error handling 
} 

} 

//Code to delete the file - 
int remove_file (const char* name) 
{ 
    if ((err = unlink(name)) == -1) 
    { //Error handling } 
} 

EDIT3 正如指出的約阿希姆Pileborgicabod,如果它仍然是打開DeleteFile()不會刪除文件。如Remy Lebeau所示,使用進程管理器。我發現有一個句柄的文件確實是開放的,當我關閉,從進程管理器文件中刪除就像一個魅力:)

我曾在EDIT1還提到,當我試圖接近我得到一個錯誤的文件。發生這種情況是因爲從createfile()獲得的文件描述符不是由CreateFile()API返回的實際句柄,而是由於底層代碼複雜性而支持其他非Windows平臺的邏輯映射句柄。無論如何,現在我明白問題的根本原因,但我期待如果打開句柄的文件傳遞給DeleteFile() API,那麼它應該在第一次嘗試失敗而成功並等待打開的句柄關閉。

+4

你說「沒有其他程序正在訪問除試圖刪除此文件的程序以外的文件」。這是否意味着你的程序中打開了文件(例如'open','fopen'或'CreateFile')?然後,不會因爲程序仍然打開而從磁盤中刪除它。如果你先關閉文件,然後*刪除它,它應該工作。 – 2014-12-03 11:21:33

+1

我覺得很奇怪,如果人們覺得問題不值得一問一答地說下去。這個問題有什麼問題? – Rahul 2014-12-03 12:48:10

+0

@JoachimPileborg如果文件仍然打開,不應該'DeleteFile'返回false? – 2014-12-03 12:55:47

回答

5

假設你打電話給你的Createfile函數,然後再打電話給remove_file函數......你仍然有一個處理文件的句柄。 WinAPI函數CreateFile,如果成功,則在文件上保持句柄打開。在您提供的代碼中,您不關閉該句柄。

從文檔上DeleteFile

的功能的DeleteFile標誌着在近刪除的文件。因此,直到該文件的最後一個句柄關閉,文件刪除纔會發生。隨後調用CreateFile打開文件失敗,並顯示ERROR_ACCESS_DENIED。

我的猜測是,你仍然有一個句柄打開,當你關閉該句柄時,該文件將被刪除。

但是,您的示例代碼是不完整的,因此很難說。

+1

您可以使用像SysInternals Process Explorer這樣的工具來找出誰有被刪除文件的開放句柄。 – 2014-12-03 17:39:17

+0

是的,PE對此非常有用。我會注意到'你不應該用它來強制關閉句柄 - 正如[Raymond Chen指出](http://technet.microsoft.com/en-us/magazine/2009.04.windowsconfidential.aspx),它可能會很糟糕。最好確保關閉所有自己的手柄,並且如果您擔心其他人訪問該文件,請不要使用「SHARED」訪問權限打開它。 – icabod 2014-12-04 11:37:44

相關問題