DropBox 会干扰 DeleteFile()/rename() 吗?

Could DropBox interfere with DeleteFile()/rename()

本文关键字:rename DeleteFile DropBox 干扰      更新时间:2023-10-16

我有以下代码,每两个执行一次 一整天分钟数:

int sucessfully_deleted = DeleteFile(dest_filename);
if (!sucessfully_deleted)
{
// this never happens
}
rename(source_filename,dest_filename);

每隔几个小时,rename(( 就会失败一次,并显示 errno=13 (EACCES(。所涉及的文件都位于DropBox目录中,我有一种预感,DropBox可能是原因。我认为 DeleteFile(( 函数可能会返回非零successfully_deleted但实际上 DropBox 可能仍然忙于做一些与阻止 rename(( 成功的删除有关的事情。我接下来要做的是将 rename(( 更改为 my_rename((,这将尝试 rename((,并且在任何失败时都会 Sleep(( 一秒钟并尝试第二次。果然,从那以后一直完美地工作。更重要的是,我每隔几个小时就会收到一条诊断消息,显示首次尝试失败。它在第二次尝试中从未失败过。

所以你可以说问题完全解决了...但我想了解可能发生的事情,以便将来更好地保护自己免受任何相关 Dropbox 问题的侵害......

真的,我想要一个新的 super_delete(( 函数,在文件被正确删除并在所有方面完成之前,它不会返回。

在 Windows 请求下删除文件真的永远不会删除文件。 它用特殊标志(FCB_STATE_DELETE_ON_CLOSE(将其标记为FCB(文件控制块(。 只有当最后一个文件句柄关闭时,才会真正删除。

DeleteFile函数在关闭时标记要删除的文件。因此 在文件的最后一个句柄之前,不会删除文件。 闭。对打开文件的后续CreateFile调用失败,并显示ERROR_ACCESS_DENIED.

此外,如果存在部分(内存映射文件(在文件上打开 - 文件甚至不能标记为删除。 API 调用失败,STATUS_CANNOT_DELETE. 所以一般来说不可能总是删除文件。

如果存在文件的另一个打开句柄(但不是部分!(从 Windows 10 RS1 开始存在删除新功能 -FileDispositionInformationExFILE_DISPOSITION_POSIX_SEMANTICS. 在这种情况下:

通常,标记为删除的文件实际上不会被删除,直到所有 文件的打开句柄已关闭,并且 文件为零。使用 标记要删除的文件时FILE_DISPOSITION_POSIX_SEMANTICS,一旦 POSIX 删除句柄关闭,链接就会从可见命名空间中删除, 但该文件的数据流仍可由其他现有数据流访问 句柄,直到最后一个句柄关闭。

ULONG DeletePosix(PCWSTR lpFileName)
{
HANDLE hFile = CreateFileW(lpFileName, DELETE, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
static FILE_DISPOSITION_INFO_EX fdi = { FILE_DISPOSITION_DELETE| FILE_DISPOSITION_POSIX_SEMANTICS };
ULONG dwError = SetFileInformationByHandle(hFile, FileDispositionInfoEx, &fdi, sizeof(fdi)) 
? NOERROR : GetLastError();
// win10 rs1: file removed from parent folder here
CloseHandle(hFile);
return dwError;
}

更新

抱歉,我第一次没有正确回答问题。我以为删除文件返回错误 13。

现在我明白了 DeleteFile 成功,但重命名之后立即失败。这可能只是文件系统的同步问题。调用 DeleteFile 后,当操作系统提交对文件系统的更改时,该文件将被删除。这可能不会立即生效。 如果需要对同一路径执行多个操作,则应查看 https://learn.microsoft.com/it-it/windows/desktop/api/winbase/nf-winbase-deletefiletransacteda 事务。

--旧答案 --

这是正确的。如果另一个应用程序处理该文件,则删除文件将失败。 引用 MSDN 文档 https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-deletefile:

The DeleteFile function fails if an application attempts to delete a file that has other handles open for normal I/O or as a memory-mapped file (FILE_SHARE_DELETE must have been specified when other handles were opened).

这适用于 dropbox、防病毒软件或通常可能打开这些文件的任何其他应用程序。 Dropbox 可能随时打开文件以计算其哈希值(以查找更改(。防病毒软件也是如此。