DropBox 会干扰 DeleteFile()/rename() 吗?
Could DropBox interfere with DeleteFile()/rename()
我有以下代码,每两个执行一次 一整天分钟数:
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 开始存在删除新功能 -FileDispositionInformationEx
与FILE_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 可能随时打开文件以计算其哈希值(以查找更改(。防病毒软件也是如此。
- DropBox 会干扰 DeleteFile()/rename() 吗?
- 在 Windows QDir::mkpath 和 QFile::rename 上报告成功,尽管失败了
- "Rename"派生类中的成员变量
- linux 是否"rename"函数调用块,直到复制(当源和目标在不同磁盘中时)完成
- 尝试使用窗口注册表中的路径和 DeleteFile() 方法删除.exe文件
- DeleteFile,以子字符串开头
- DeleteFile (kernel32.dll) vs DeleteItem (shell32.dll)
- rename()返回-1.如何知道重命名失败的原因
- 如何在不使用继承的情况下'rename'模板实例化?
- rename():尽管完全控制,但访问被拒绝
- 如何使用rename()函数(c++)用字符串重命名文件
- 当使用字符变量作为参数(字符串转换为字符)时,Std::rename()文件将不起作用
- c++中如何使用带有通配符的DeleteFile
- QDir::rename:冗余参数
- Rename()函数在尝试向文件添加扩展名时不起作用