我正面临这个奇怪的问题。 要删除文件,请在我的代码中调用unlink() API。此调用将删除该文件并在非Windows平台上成功。在Windows上它成功(返回0)但不删除该文件。
为了实验,我添加了一个循环来重复调用相同的API。在第二次迭代中,我得到了一个Permission denied错误,错误代码= 13。虽然在文件中设置了读/写属性,但程序具有访问该文件的完全权限。
然后我调用DeleteFile()而不是unlink()API。令我惊讶的是,我看到相同的结果,调用成功,即返回1但文件未被物理删除。
我检查了解锁工具,除了试图删除此文件的程序外,没有其他程序正在访问该文件。
有谁知道还有什么可能是错的?
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 所建议的那样,使用进程资源管理器。我发现文件的一个句柄确实是打开的,当我从过程资源管理器文件中删除它时就像一个魅力:)
我在 Edit1 中也提到过,当我尝试关闭文件时出现错误。之所以发生这种情况是因为我从createfile()
获取的文件描述符不是CreateFile()API返回的实际句柄,而是逻辑映射句柄,因为底层代码复杂性支持其他非Windows平台。无论如何,现在我理解了问题的根本原因但是我期待如果一个带有打开句柄的文件被传递给DeleteFile()
API,那么它应该在第一次尝试失败然后成功并等待打开句柄关闭。
答案 0 :(得分:5)
假设您调用Createfile
函数,然后再调用remove_file
函数...您仍然可以打开文件句柄。 WinAPI函数CreateFile
如果成功,则在文件上保持句柄打开。在您提供的代码中,您不会关闭该句柄。
来自DeleteFile的文档:
DeleteFile函数在关闭时标记要删除的文件。因此,在关闭文件的最后一个句柄之前不会发生文件删除。随后调用CreateFile以打开文件失败,并显示ERROR_ACCESS_DENIED。
我的猜测是你仍然有一个句柄打开,当你关闭该句柄时,文件将被删除。
但是,您的示例代码不完整,因此很难说清楚。