删除的文件仍报告为现有文件(仅Windows)

时间:2018-07-12 09:00:42

标签: c++ windows qt filesystems ntfs

(请注意,这主要不是Qt问题)

在我看来QFile::exists()的返回值有时是错误的。

考虑以下两个类似于单元测试的代码片段(每个代码片段我都循环执行了数千次)

// create file
QFile file("test.tmp");
QVERIFY(file.open(QIODevice::WriteOnly));
QVERIFY(file.write("some data") != -1);
file.close();

// delete file
QVERIFY(file.remove());

// assert file is gone
QVERIFY(!file.exists());  // <-- 5..10 % chance of failure

// create file
QFile file("test.tmp");
QVERIFY(file.open(QIODevice::WriteOnly));
QVERIFY(file.write("some data") != -1);
file.close();

// delete file
QVERIFY(file.remove());

// retry until file is gone (or until timeout)
for (auto i = 0; i < 10; i++)
{
  if (!file.exists())  // <-- note that only the check is retried, not the actual delete
    return;

  QThread::yieldCurrentThread();
}

QFAIL("file is still reported as existing");  // <-- never reached in my tests

第一次单元测试失败100次中有8次失败。始终在代码的最后一行(指示该文件仍然存在)。第二个单元测试永远不会失败。

在使用NTFS(带有Qt 5.2.1)的Windows 10系统上观察到此行为。无法在使用ext4的ubuntu 16.04 LTS上在VM(带有Qt 5.8.0)上复制

不确定这是否有帮助:

所以我的问题是:

  • 发生了什么事?
  • 我可能感兴趣的是什么?

更新:

为澄清起见:我希望得到这样的答案:“ 这是由NTFS功能'bills-fancy-caching-magic'引起的”。我想从那里找出Qt是否确实有意检查此功能。

1 个答案:

答案 0 :(得分:0)

根据Windows API documentation,它被定义为行为:

  

DeleteFile函数将文件标记为在关闭时删除。因此,在关闭文件的最后一个句柄之前,不会发生文件删除。随后调用CreateFile打开文件失败,错误代码为ERROR_ACCESS_DENIED。

这似乎是Windows内核的属性,因此不限于NTFS。

该行为似乎无法预测,因为其他服务(例如病毒扫描程序)可能会打开有问题的文件。