Почему FindFirst возвращает имена файлов, которые не соответствуют маске?

Я передаю значение параметра '*1.dat' в FindFirst, но первый файл, возвращаемый функцией FindFirst(), 46checks5.dat, очень последовательно.

Является ли это известной проблемой?

vpath:=trim(vpath);
result:=true;
try
  res:=findfirst(vpath+'\'+vmask,faarchive,search);    //vmask = *1.dat
  try 
    while res=0 do
    begin
      vlist.add(search.name);   //searchname returned is 46checks5.dat!!!
      res:=findnext(search);
    end;
  finally
    findclose(search);
  end;
except
  result:=false;
end;

Ответы

Ответ 1

Причина в том, что файл имеет "длинное" имя, то есть более 8 символов. Для таких файлов Windows также создает "короткие" имена, которые обычно создаются в форме longna~1.dat, и это короткое имя встречается с помощью *1.dat подстановочного знака.

Вы можете легко воспроизвести такое же поведение в командной строке в пустом каталоге:

C:\TEMP>echo. > 46checks5.dat 
C:\TEMP>dir /x *1.dat
 Volume in drive C has no label.
 Volume Serial Number is 5C09-D9DE

 Directory of C:\TEMP

2011.04.15  21:37                 3 46CHEC~1.DAT 46checks5.dat
               1 File(s)              3 bytes

Документация для FindFirstFile(), которая является базовым API для FindFirst:

Поиск включает в себя длинные и короткие имена файлов.

Чтобы обойти эту проблему, вместо использования оболочки Delphi на FindFirstFile(), вызовите API Win32 FindFirstFileEx(). Перейдите FindExInfoBasic к параметру fInfoLevelId.

Ответ 2

У вас что-то еще не так.

Я создал папку C:\Temp\Test и поместил в нее три файла:

TestFile1.txt
TestFile2.txt
TestFile3.txt

Затем я опустил TMemo в новую пустую форму в новом проекте и добавил этот код в событие FormCreate:

procedure TForm1.FormCreate(Sender: TObject);
var
  sPath: string;
  sFile: string;
  SR: TSearchRec;
begin
  sPath := 'C:\Temp\Test';
  sFile := '*1.txt';

  Memo1.Lines.Clear;
  if FindFirst(sPath + '\' + sFile, faArchive, SR) = 0 then
  begin
    try
      repeat
        Memo1.Lines.Add(SR.Name);
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
  end;
end;

Когда форма была показана, TMemo показал ровно один файл, TestFile1.txt, как и ожидалось.