【问题标题】:Is there an alternative to the Windows FindFirstFile/FindNextFile API that doesn't search short file names?是否有不搜索短文件名的 Windows FindFirstFile/FindNextFile API 的替代方法?
【发布时间】:2011-12-25 14:15:50
【问题描述】:

我正在使用 Windows API 调用 FindFirstFileFindNextFile 在目录中搜索与某个通配符字符串匹配的文件。例如,我可能想查找目录中的所有 XML 文件,因此我使用模式“*.xml”进行搜索。

我遇到的问题是,如果我正在搜索 3 个字母的扩展名,并且文件的扩展名以该 3 个字母的扩展名开头,即使扩展名包含更多内容,它也会被我的搜索选中前 3 个字符之后的字符。例如,如果我的文件名为 somelongname.xmlaaaa,则搜索“*.xml”将获取该文件。该文件的短名称是 somelo~1.xml,它与我的通配符字符串匹配。

我可以自己进行通配符匹配来解决这个问题,但大概 Windows API 能够比我更有效地做到这一点,而且我的代码会更简单。据我所知,没有办法强制这些函数忽略短名称。是否有任何 API Windows 公开了此功能?

【问题讨论】:

    标签: c++ c windows winapi filesystems


    【解决方案1】:

    查看 FindFirstFileEx - 它有一个采用 FINDEX_INFO_LEVELS 枚举的 fInfoLevelId 参数:

    typedef enum _FINDEX_INFO_LEVELS {
      FindExInfoStandard,
      FindExInfoBasic,
      FindExInfoMaxInfoLevel 
    } FINDEX_INFO_LEVELS;
    

    FindExInfoBasic

    FindFirstFileEx 函数不查询短文件名,提高了整体枚举速度。数据以 WIN32_FIND_DATA 结构返回,cAlternateFileName 成员始终为 NULL 字符串。

    但是:

    Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:直到 Windows Server 2008 R2 和 Windows 7 才支持此值。

    【讨论】:

    • 有趣。我需要支持 Windows XP,所以我可能无法依赖此功能。不幸的是,它被添加到 Windows 7 中的这个 API 的事实可能表明它在此之前不存在于任何其他 API 中。
    • 看起来是这样的。很抱歉让你失望了 :) 感谢您的编辑,@Rob
    • 事实证明这个文档非常具有误导性。即使您传入 FindExInfoBasic,搜索仍会找到与短名称匹配的文件。它只是不会在 WIN32_FIND_DATA 结构的 cAlternateFileName 成员中包含短文件名。
    • 我确实发现有一个 Windows 函数 PathMatchSpec 将对提供的字符串执行相同的通配符匹配。因此,我能够在搜索中添加第二步,以验证长名称是否与模式匹配。感谢您的帮助@JoeFish!
    • @ChrisVasselli 为什么不将其发布为答案?我认为这将有助于未来有同样问题的访问者..
    【解决方案2】:

    不幸的是,JoeFish 在他的回答中找到的文档被证明有点误导。即使您传入 FindExInfoBasic,搜索仍会找到与短名称匹配的文件。它只是不会在 WIN32_FIND_DATA 结构的 cAlternateFileName 成员中包含短文件名。

    然而,我确实发现有一个 Windows 函数 PathMatchSpec 将对提供的字符串执行相同的通配符匹配。因此,我能够在搜索中添加第二步,以验证长名称是否与模式匹配。它甚至可以在 Windows XP 中使用。

    【讨论】:

      猜你喜欢
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      • 2013-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多