Как избежать ложных срабатываний CFileFind с расширением файла длиннее трех символов?
Когда я пытаюсь позвонить CFileFind.FindFile(_T("D://Folder//*.txt"))
, метод возвращает true, если единственным файлом является "foobar.txta".
Однако я не хочу, чтобы файл foobar.txta включал результат поиска. Как мне сделать это таким образом? Возможно, используя другой метод или другой, если? Я новичок в C++:))
Примечание. Эта проблема, по-видимому, не возникает, если расширение меньше 3, например, если для фильтра задано "*.tx", а для файла - "foobar.txt", метод по-прежнему (правильно) возвращает false. Кроме того, проблема, кажется, сообщается здесь, но кажется, что мне нужно заплатить, чтобы увидеть решение
4 ответа
Как отметили другие авторы, очевидная ошибка заключается в том, что файл Windows имеет псевдоним 8.3, в результате чего "foobar.txta" определяется как "foobar.txt". Чтобы убедиться, что файл, найденный CFileFind, действительно соответствует шаблону с подстановочными знаками, используйте 'PathMatchSpec', чтобы проверить файл, возвращенный функцией finder.GetNextFile(). PathMatchSpec
кажется, не влияет псевдоним 8.3.
Кажется, это ошибка в 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" могут иметь короткий синоним. Т.е. "foobar.txta"
также называется "foobar.txt"
, Если вы действительно имели в виду только *.txt
, вам придется вручную проверить результаты. Эти результаты будут использовать длинное имя, поэтому вы можете отказаться от *.txt?
файлы
Вы можете сделать ручную проверку впоследствии с PathMatchSpec("foobar.txta", "*.txt")
, Обратите внимание, что, несмотря на название, эта функция действительно подходит только для сопоставления расширений. Не ожидайте ничего кроме *.ext
работать.
Я надеюсь, что это сработает.
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
Теперь это можно извлечь.