相关疑难解决方法(0)

C++/Win32:如何等待挂起删除完成?

解决:
*可行的解决方案:@sbi
*解释实际发生的事情:@Hans
*解释为什么OpenFile没有通过"DELETE PENDING":@Benjamin

问题:
我们的软件在很大程度上是专有脚本语言的解释器引擎.该脚本语言能够创建文件,处理文件,然后删除文件.这些都是单独的操作,并且在这些操作之间没有保持打开文件句柄.(即在文件创建过程中创建一个句柄,用于写入,然后关闭.在文件处理部分,一个单独的文件句柄打开文件,从中读取,并在EOF关闭.最后,删除使用:: DeleteFile它只使用文件名,而不是文件句柄.

最近我们开始意识到特定的宏(脚本)有时无法在随后的某个随机时间创建文件(即它在"创建,处理,删除"的前100次迭代中成功,但是当它到来时回到创建它一百零一次,Windows回复"拒绝访问").

深入研究这个问题,我编写了一个非常简单的程序,它循环遍历这样的事情:

while (true) {
    HANDLE hFile = CreateFileA(pszFilename, FILE_ALL_ACCESS, FILE_SHARE_READ,
                               NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return OpenFailed;

    const DWORD dwWrite = strlen(pszFilename);
    DWORD dwWritten;

    if (!WriteFile(hFile, pszFilename, dwWrite, &dwWritten, NULL) || dwWritten != dwWrite)
        return WriteFailed;

    if (!CloseHandle(hFile))
        return CloseFailed;

    if (!DeleteFileA(pszFilename))
        return DeleteFailed;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这直接针对Win32 API,非常简单.我创建一个文件,写入它,关闭句柄,删除它,冲洗,重复...

但是在某些地方,我会在CreateFile()调用期间收到Access Denied(5)错误.看看sysinternal的ProcessMonitor,我可以看到底层的问题是当我试图再次创建它时,文件上有一个挂起的删除.

问题:
*有没有办法等待删除完成?
*有没有办法检测文件是否正在等待删除?

我们通过HFILE上的WaitForSingleObject()尝试了第一个选项.但是,在WaitForSingleObject执行之前,HFILE始终处于关闭状态,因此WaitForSingleObject始终返回WAIT_FAILED.显然,试图等待关闭的句柄不起作用.

我可以等待文件存在的文件夹的更改通知.但是,这似乎是一个非常开销密集的kludge只是偶尔会出现问题(也就是说:在我的Win7 x64 E6600 PC的测试中,它通常会失败迭代12000+ - 在其他机器上,它可以在迭代7或15或56或永远不会发生.

我无法识别任何明确允许此以太的CreateFile()参数.无论CreateFile有什么参数,当文件待删除时打开文件进行任何访问都是不行的.由于我可以在XP盒子和x64 Win7盒子上看到这种行为,我很确定这是微软的"按照预期"的核心NTFS行为.所以我需要一个允许操作系统在我尝试继续之前完成删除的解决方案,最好是不必要地占用CPU周期,并且没有观察该文件所在文件夹的极端开销(如果可能的话).

感谢您抽出宝贵时间阅读并发布回复.澄清问题欢迎!

[1]是的,这个循环返回写入失败或无法关闭哪个泄漏,但由于这是一个简单的控制台测试应用程序,应用程序本身退出,Windows保证所有句柄在操作系统关闭时完成.所以这里没有泄漏.

bool DeleteFileNowA(const char …
Run Code Online (Sandbox Code Playgroud)

c++ file-io winapi ntfs

31
推荐指数
3
解决办法
1万
查看次数

标签 统计

c++ ×1

file-io ×1

ntfs ×1

winapi ×1