如何避免 CFile查找文件扩展名超过三个字符的误报

How to avoid CFileFind false positive with file extension longer than three characters?

本文关键字:三个 字符 查找 CFile 何避免 文件 扩展名      更新时间:2023-10-16

当我尝试调用CFileFind.FindFile(_T("D://Folder//*.txt"))时,当唯一的文件是"foobar.txta"时,该方法返回true。

但是,我不希望文件foobar.txta包含在查找结果中。我该怎么做到呢?可能通过使用其他方法或其他方法?我是C++ :)的新手)

注意:如果exension小于3,则似乎不会发生此问题,例如,如果过滤器为"*.tx"并且文件为"foobar.txt",则该方法仍然(正确)返回false。另外,这个问题似乎在这里报告,但似乎我需要付费才能看到解决方案

这似乎是CFindFile(或Win32 API FindFirstFile)中的一个错误。但是你可以稍后通过调用CFindFile::GetFileName来确定真正的扩展名:

CFindFile finder;
BOOL bWorking = finder.FindFile(L"*.txt");
while (bWorking)
{
    bWorking = finder.FindNextFile();
    if (finder.GetFileName().Right(finder.GetFileName().ReverseFind(L'.')) != L".txt")
        // the file extension is not .txt
}

这是向后兼容的常见 Windows 行为。没有"8.3"名称的文件可能具有简短的同义词。J.F. "foobar.txta"也称为"foobar.txt"。如果您确实只是想*.txt,则必须手动检查结果。这些结果将使用长名称,因此您可以丢弃*.txt?文件

之后您可以使用PathMatchSpec("foobar.txta", "*.txt")进行手动检查。请注意,尽管名称如此,但此函数实际上仅适用于扩展匹配。不要指望除了*.ext才能起作用。

参见 是否有不搜索短文件名的 Windows FindFirstFile/FindNextFile API 的替代方法?

我希望这会起作用。

WIN32_FIND_DATA ffd;
    CStringList strFileNameList;
    CStringList strFileMask;
    int iCntFiles = 0;
    HANDLE          hFind     = INVALID_HANDLE_VALUE;
 CONST CHAR cszFileName[] = "test.txt";
 strFileMask = strFileName.Left(strFileName.Find(cszFileName)) + "*.txt";
    hFind          = FindFirstFile(strFileMask.GetBufferSetLength(strFileMask.GetLength()), &ffd);
    if (INVALID_HANDLE_VALUE == hFind) 
    {
        return;
    } 
    else
    {
        // List all the other files in the directory.
        strFileNameList.AddTail(ffd.cFileName);
        iCntFiles++;
        while (FindNextFile(hFind, &ffd) != 0) 
        {
            strFileNameList.AddTail(ffd.cFileName);
            iCntFiles++;
        }
}

现在从保存在CStringList中的所有文本文件中现在可以提取它。

正如其他回答者所指出的,明显的错误是因为Windows文件具有8.3别名,导致"foobar.txta"被检测为"foobar.txt"。要确保 CFileFind 找到的文件确实与通配符模式匹配,请使用"PathMatchSpec"来验证 finder 返回的文件。GetNextFile()。 PathMatchSpec似乎不受 8.3 别名的影响。