Почему FindFirst возвращает имена файлов, которые не соответствуют маске? - PullRequest
14 голосов
/ 15 апреля 2011

Я передаю значение параметра '*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;

Ответы [ 2 ]

23 голосов
/ 15 апреля 2011

Причина в том, что файл имеет «длинное» имя, то есть более 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(), вызовите Win32 API FindFirstFileEx().Передайте FindExInfoBasic параметру fInfoLevelId.

0 голосов
/ 15 апреля 2011

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

Я создал папку 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, как я и ожидал.

...