17

I pass the parameter value '*1.dat' to FindFirst, still the first file that the FindFirst() routine return is 46checks5.dat, very consistently.

Is this a known problem?

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;
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
Blow ThemUp
  • 895
  • 6
  • 18
  • 29

2 Answers2

26

The reason is that the file has a "long" name, i.e. with more than 8 characters. For such files Windows also creates "short" names, that usually are created in the form longna~1.dat and this short name is found via *1.dat wildcard.

You can easily reproduce the same behaviour in command prompt in an empty directory:

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

The documentation for FindFirstFile(), which is the underlying API for FindFirst states:

The search includes the long and short file names.

To workaround this issue, then, rather than using Delphi's wrapper to FindFirstFile(), call the Win32 API FindFirstFileEx(). Pass FindExInfoBasic to the fInfoLevelId parameter.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
andrius
  • 693
  • 4
  • 8
  • yes, i saw that here: http://blog.excastle.com/2007/10/01/83-backward-compatibility-or-why-dpr-returns-dproj-files/ however, that doesn't solve my question. Is there a fix to this, a work around, or an alternative solution? – Blow ThemUp Apr 15 '11 at 18:50
  • 2
    @user I have taken the liberty of adding the workaround to the answer. – David Heffernan Apr 15 '11 at 18:55
  • Thanks David, i will give that a test – Blow ThemUp Apr 15 '11 at 20:11
  • 1
    +1. Nice catch. I'm not sure why my code didn't have the same issue, though. – Ken White Apr 16 '11 at 20:24
  • Note: a file may have a "long" name for various other reasons, e.g. it might contain multiple periods, spaces or certain other characters, or have an extension of more than 3 characters. In particular, the latter means that a file with an extension such as ".data" will also be given a separate short name, e.g. "FILE~1.DAT", which will also match the *.dat wildcard. – mwfearnley Jun 21 '13 at 19:47
0

You have something else wrong.

I created a folder C:\Temp\Test, and put three files in it:

TestFile1.txt
TestFile2.txt
TestFile3.txt

I then dropped a TMemo on a new blank form in a new project, and added this code to the 'FormCreate' event:

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;

When the form was shown, the TMemo showed exactly one file, TestFile1.txt, just as I would expect.

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • I created three files (461checksa1.dat, 46checks1.dat, 46checksa1.dat, 46checks5.dat) and using your code, everyone of the files was shown in the memo, including the last one, which has no '1' in the file name! – Blow ThemUp Apr 15 '11 at 17:43
  • sorry, i meant I created four files (one of them missing a '1' in the name) – Blow ThemUp Apr 15 '11 at 17:48
  • As I said, you have something wrong. I just copied my existing `TestFile1.txt` to make four files named the same as yours (including extension), and modified my code to look for `*1.dat` instead of `*1.txt`. I got three file listed in the memo: `461checksa1.dat, 46checks1.dat, and 46checksa1.dat`. The only change in my code was to change the extension in the `sFile` variable from `.txt` to `.dat` – Ken White Apr 15 '11 at 18:36
  • How could i have anything wrong. I created a new project, and used your exact code above. My form, had just a memo, and i used your code in the OnCreate event. – Blow ThemUp Apr 15 '11 at 20:05