DropBox可能会干扰DeleteFile()/ rename()

时间:2018-10-07 09:58:38

标签: c++ c visual-studio windows-10 dropbox

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

int sucessfully_deleted = DeleteFile(dest_filename);

if (!sucessfully_deleted)
{
    // this never happens
}

rename(source_filename,dest_filename);

每隔几个小时,rename()将失败,并出现errno = 13(EACCES)。所涉及的文件全部位于DropBox目录中,我直觉Dropbox可能是原因。我认为DeleteFile()函数可能会返回一个非零的success_deleted,但实际上DropBox可能仍在忙于做一些与删除操作有关的事情,这些操作阻止了named()成功。接下来,我要做的是将rename()更改为my_rename(),这将尝试进行rename(),一旦失败,将Sleep()停留一秒钟,然后再次尝试。从那以后,果然如此完美。此外,每隔几个小时,我会收到一条诊断消息,显示首次尝试失败。在第二次尝试中从未失败。

所以您可以说问题已完全解决...但是我想了解可能会发生什么,以便将来更好地保护自己免受任何相关的DropBox问题...

真的,我想拥有一个新的super_delete()函数,该函数要等到正确删除并在各个方面完成后才返回。

2 个答案:

答案 0 :(得分:3)

Windows下的

请求删除文件实际上从未只是删除文件。并用特殊标志(FCB_STATE_DELETE_ON_CLOSE)将其标记为 FCB 文件控制块)。仅当最后一个文件句柄关闭时,才真正删除。

  

DeleteFile函数将文件标记为关闭时要删除。因此,   直到文件的最后一个句柄是   关闭。随后调用CreateFile打开文件失败   ERROR_ACCESS_DENIED

如果存在的部分(内存映射文件)在文件上打开-甚至无法将文件标记为删除。 api调用失败,STATUS_CANNOT_DELETE。因此通常不可能总是删除文件。

如果存在从Windows 10 rs1开始的另一个文件打开句柄(但不是section!),则存在删除的新功能-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;
}

答案 1 :(得分:1)

更新

对不起,我第一次没有正确回答问题。我以为DeleteFile返回错误13。

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

-旧答案-

是正确的。如果另一个应用程序处理该文件,则DeleteFile将失败。 引用MSDN文档https://docs.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随时可以打开文件以计算其哈希值(以查找更改)。防病毒软件也是如此。