2014-12-03 76 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

相关问题