【问题标题】:Does FindFirstFile/FindNextFile API pair cache results returned?FindFirstFile/FindNextFile API 对缓存结果是否返回?
【发布时间】:2014-06-07 19:36:56
【问题描述】:

我不确定这是否已经被问过,我似乎找不到它。

当我在做一个文件夹内容枚举时,你知道通常的做法:

FindFirstFile();
do
{
}while(FindNextFile());

如果我仍在do/while 循环中时文件夹的内容发生了变化,会发生什么情况?比如说,添加、更改或删除了一个新文件或文件夹。这是否反映在FindNextFile 返回的结果中?

【问题讨论】:

  • 虽然我不知道答案,但通过在循环中添加足够几秒钟的 Sleep 语句很容易找到,这样您就可以在循环进行时删除文件并查看自己。
  • 这个问题似乎没有实际意义,因为你总是有一个TOCTOU 竞争条件。 FindFirstFile 明确说明了这一点:“请注意,在查询结果和对信息采取行动之间,某些其他线程或进程可能会创建或删除具有此名称的文件。”
  • @IInspectable:好的,好点。所以答案是,不。结果是“实时”获取的。所以,我问的原因是因为我正在编写一个移动文件夹内容的方法,所以在这种情况下,如果我开始移动文件(或从文件夹中删除它们),它可能会影响 FindNextFile 返回的结果对吧?
  • 我会运行并将文件提取到某种列表中,然后在您完成该过程后处理所有文件。如果您一次执行一个目录(从最深级别开始),您可以在完成复制/删除操作后运行第二次扫描以检查新文件[这当然可能需要相当长的时间]。
  • 您可能会或可能不会看到循环期间发生的任何特定更改。您需要应对这两种情况。

标签: c++ windows winapi


【解决方案1】:

一个快速的测试用例表明 FindFirstFile 不会将结果缓存在 Windows 7 上运行的本地文件系统上。但是一旦调用 FindNext,结果就会被缓存(不完全缓存,只有一点点)。但由于 Windows SDK 中没有记录这一点,因此必须将其视为实现细节,随时可能发生变化。因此,以不依赖于这种行为的方式编写代码。

【讨论】:

  • 没有完全缓存。 (在拥有一百万个文件的目录中,这将是可怕的。)它只缓存了一点点。这种行为不是契约性的,可以随时改变。如果要缓存全部内容,需要自己做。
  • 我已经怀疑它不会完全缓存包含这么多文件的目录。我已经更新了我的答案以使其更加清晰。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2014-05-26
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多