C DeleteFile()或unlink()调用成功,但不';不要删除文件
我面临着这个奇怪的问题。 在我的代码中调用了删除文件的API。此调用将删除文件并在非windows平台上成功。在windows上,它会成功(返回0),但不会删除该文件C DeleteFile()或unlink()调用成功,但不';不要删除文件,c,windows,winapi,win32-process,C,Windows,Winapi,Win32 Process,我面临着这个奇怪的问题。 在我的代码中调用了删除文件的API。此调用将删除文件并在非windows平台上成功。在windows上,它会成功(返回0),但不会删除该文件 // Code to create the file int create_file(const char* path) { HANDLE osfh; /* OS handle of opened file */ DWORD fileaccess;
// 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 }
}
为了进行实验,我添加了一个循环来重复调用相同的API。在第二次迭代中,我得到了一个权限被拒绝的错误,错误代码=13。尽管在文件上设置了读/写属性,并且程序具有访问该文件的完全权限
// 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 }
}
然后我调用了而不是unlink()API。令我惊讶的是,我看到了相同的结果,调用成功,即返回1,但文件没有被物理删除
我通过unlocker实用程序进行了检查,除了试图删除该文件的程序外,没有其他程序正在访问该文件
有人知道还有什么问题吗
Edit1:
只是为了确保文件在删除时未被打开。我在创建文件时保存了句柄,并试图在删除文件之前关闭,但出现错误“'UNOPENED'(错误代码:9-错误的文件描述符)”。因此,我得出结论,文件在删除时未打开
Edit2
根据要求,以下是用于创建和删除文件的简化版本代码
// 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
正如Joachim Pileborg和icabod所指出的那样,DeleteFile()
不会删除仍然打开的文件。按照Remy Lebeau的建议,使用process explorer。当我从process explorer文件中关闭该文件时,我发现该文件的一个句柄确实打开了,就像一个符咒一样被删除:)
我在Edit1中也提到,当我试图关闭文件时,出现了一个错误。之所以发生这种情况,是因为我从
createfile()
获取的文件描述符不是createfile()API返回的实际句柄,而是一个逻辑映射句柄,因为底层代码复杂,无法支持其他非windows平台。无论如何,现在我理解了问题的根本原因,但我希望如果将具有打开句柄的文件传递给DeleteFile()
API,那么它应该在第一次尝试中失败,而不是成功,并等待打开句柄关闭。假设您调用Createfile
函数,然后稍后调用您的remove\u文件
函数。。。您仍然有一个文件的句柄打开。WinAPI函数CreateFile
,如果成功,将保持文件上的句柄打开。在提供的代码中,不关闭该句柄
从以下文件:
DeleteFile函数在关闭时标记要删除的文件。因此,在关闭文件的最后一个句柄之前,不会删除文件。后续调用CreateFile以打开文件失败,错误为\u访问被拒绝
我猜您仍然有一个句柄处于打开状态,当您关闭该句柄时,文件将被删除
但是,您的示例代码不完整,因此很难判断。您说“除了试图删除此文件的程序外,没有其他程序正在访问该文件”。这是否意味着您已经在程序中打开了文件(例如,
open
、fopen
或CreateFile
)?然后不,它将不会从磁盘上删除,因为您的程序仍然打开它。如果你先关闭文件,然后删除它,它应该会起作用。如果人们觉得这个问题不值得问,我觉得很奇怪,在否决投票的同时也这么说。这个问题怎么了?@JoachimPileborg如果文件仍然打开,不应该DeleteFile
返回false吗?@Rahul发布一些代码。顺便说一句,\u unlink
除了调用DeleteFile
没有什么作用,所以如果\u unlink
失败,DeleteFile
也会失败,这其实是正常的。当DeleteFile
失败时,GetLastError()
返回什么?@MichaelWalz这取决于是否设置了FILE\u SHARE\u DELETE
标志(我想我不是Windows API的老家)。但是现在我同意是时候看看了。你可以使用SysInternals Process Explorer这样的工具来找出谁拥有被删除文件的打开句柄。是的,PE非常有用。我想指出的是,你不应该用它来强制关闭把手——因为,这可能会非常糟糕。最好确保您关闭所有自己的句柄,如果您担心其他人访问该文件,请不要使用SHARED
access打开它。