【问题标题】:Why wildcard cannot stand for directory in FindFirstFile?为什么通配符不能代表 FindFirstFile 中的目录?
【发布时间】:2017-01-17 11:12:37
【问题描述】:

我正在尝试使用FindFirstFile 来检查某些文件是否存在遵循某种模式,但通配符* 似乎不能代表目录。

int main()
{
  WIN32_FIND_DATAW findFileData;
  wchar_t path[] = LR"(.\*\*.txt)";
  HANDLE hFind = FindFirstFileW(path, &findFileData);

  if(hFind != INVALID_HANDLE_VALUE)
  {
    do
    {
      printf("%S\n", findFileData.cFileName);
    } while (FindNextFileW(hFind, &findFileData));
  }
}

使用这棵树,不会打印任何内容:

.
|- foo
|  |- some.txt
|
|- bar
|  |- another.txt

为什么会有这个限制?是否存在解决方法?

【问题讨论】:

  • 因为*\*\* 不是有效的目录名称。如果要在文件夹层次结构中搜索某些文件,则必须实现递归算法。

标签: c windows winapi


【解决方案1】:

通配符只允许在最后路径分隔符之后的文件名部分中。 documentation 确实解释了这一点。它说:

目录或路径,以及文件名。文件名可以包含通配符,例如星号 (*) 或问号 (?)。

如果您想搜索多个目录,则需要显式实现嵌套或递归迭代。

【讨论】:

  • 好的,谢谢。我不明白路径和文件名之间有正式的区别。我家是在Debian下运行的,和AFAIK没有这样的区别:在shell中,你可以随便放一个通配符。
  • @Boiethios 您无法将 shell 的通配符处理与系统调用通配符处理进行比较。 FindFirstFile 的 Linux 等价物(我认为是 opendirreaddir)不具备 shell 的功能。
  • 是的,opendir()readdir()FindFirstFile("*.*") 的等价物(特别是;任何更复杂的东西都需要您进行模式匹配),是的,它们不会跨越目录边界。 Unix libc 提供了一个函数ftw(),它将进行递归遍历;不确定 msvcrt 是否也这样做......即使那样你仍然需要自己进行模式匹配。
  • @Boiethios 您所说的globbing是在shell中实现的,据我了解,它不是系统提供的服务。
  • @DavidHeffernan glob man7.org/linux/man-pages/man3/glob.3.html 不是 shell 实现,它是 POSIX。
【解决方案2】:

正如documentation 所说:

文件名可以包含通配符,例如星号 (*) 或问号 (?)。

所以只有最后一部分可以有通配符,前面的部分必须是明确的。

您必须分两部分实现您想要的功能:首先列出所有目录,然后使用通配符列出其中的所有文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 2011-04-19
    • 2011-02-18
    • 1970-01-01
    • 2012-11-12
    相关资源
    最近更新 更多