【问题标题】:TDirectory.Delete seems to be asynchronousTDirectory.Delete 似乎是异步的
【发布时间】:2017-03-15 12:09:57
【问题描述】:

我观察到在调用 TDirectory.Delete(x) 后立即调用 DirectoryExists(x) 如果要删除的文件夹中的文件很少并且该文件夹处于打开状态(在 Total Commander 中),则返回 true。

换句话说:

begin 
  TDirectory.Delete('x', true);  <-- 'Delete' exited but the folder is still not fully deleted
  if SysUtils.DirectoryExists('x')...  <-- This returns true
end;

这是正常行为吗?

“解决方案”是这样的:

begin 
  TDirectory.Delete('x', true); 
  Sleep(1000);          //wait for Delete to finish
  if SysUtils.DirectoryExists('x')...
end;

问题:我如何知道 Delete 何时准备就绪(如何消除睡眠)?

注意:Total Commander 不会阻止删除文件夹(我猜),因为文件夹无论如何都会被删除(一段时间后)。

【问题讨论】:

  • @NAZCA:是的,我明白这一点,我只是对“你为什么……”的评论感到困惑。
  • 如果您打算清空一个文件夹,您可以为每个目录调用TDirectory.GetDirectoriesTDirectory.Delete。然后致电TDirectory.GetFiles 并将它们全部删除。这样可以节省您创建已经存在的目录的时间。现在您不再需要拨打DirectoryExists 了。是的,您需要输入更多代码,但它可以满足您的需求。
  • 你要做什么?您是否想要一个有效的程序,或者您想反对 MS 设计系统的方式。照@R.Beiboer 所说的去做。
  • 也许 msdn 页面上关于 RemoveDirectory 的备注部分给了我们一个线索? (msdn.microsoft.com/en-us/library/windows/desktop/…) RemoveDirectory 函数将目录标记为在关闭时删除。因此,在关闭目录的最后一个句柄之前不会删除该目录。这表明调用可能会在目录实际被删除之前返回。
  • @R.Beiboer - 谢谢。这为这个问题提供了一些启示。它还确认 Delete 是异步的(在 Embarcadero 的手册中没有提到)。这意味着所有使用 Delete 的代码都应该使用延迟来防止此类问题? PS:如果你发布它,我会接受你的回答。

标签: delphi delphi-xe7


【解决方案1】:

查看有关 RemoveDirectory 的 msdn 页面:https://msdn.microsoft.com/en-us/library/windows/desktop/aa365488(v=vs.85).aspx

备注部分说:

RemoveDirectory 函数将目录标记为在关闭时删除。因此,在关闭该目录的最后一个句柄之前,不会删除该目录。

所以可能另一个进程也有该目录的句柄(病毒扫描程序?)。

如果您需要清空目录,请将其清空,而不是删除它并在之后重新创建它。最后,您总是为肮脏的黑客行为付出代价;)

【讨论】:

  • 文件夹删除/重新创建可能发生的示例:Total Commander 具有允许您将 IO 操作放入队列的功能。因此,您可以删除一个文件夹,然后重新创建它(复制另一个同名的旧文件夹代替已删除的文件夹)。可能还有其他情况,您依赖于被删除的文件夹。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
相关资源
最近更新 更多