Recent

Author Topic: Findfirst() problem  (Read 7443 times)

panosdk

  • New Member
  • *
  • Posts: 16
Findfirst() problem
« on: December 11, 2021, 02:47:06 am »
Hi to all, FindFist returns 0 but the code under begin doesnt get executed. I pointing to a folder that has images. But nothing happens. Its like it didnt find any files.

Code: Pascal  [Select][+][-]
  1. SelectDirectoryDialog1.Execute;
  2. pathname:=SelectDirectoryDialog1.FileName;
  3. If FindFirst (pathname + WildcardSearch, (faAnyFile And Not faDirectory) , SearchResult) = FileFound Then
  4.    Begin
  5.    -some more code-

Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: Findfirst() problem
« Reply #1 on: December 11, 2021, 02:58:54 am »
I think you should use pathname + DirectorySeparator + WildcardSearch.

panosdk

  • New Member
  • *
  • Posts: 16
Re: Findfirst() problem
« Reply #2 on: December 11, 2021, 04:15:36 am »
Thank for the reply. I still get the same result. I am on linux btw.

GAN

  • Sr. Member
  • ****
  • Posts: 370
Re: Findfirst() problem
« Reply #3 on: December 11, 2021, 04:29:43 am »
Thats work fine on Linux:

Code: Pascal  [Select][+][-]
  1. procedure LoadArch(PathName);
  2. var
  3.   Arch:TSearchRec;
  4. begin
  5.     if FindFirst(PathName+'*',not faHidden and not faDirectory,Arch)=0 then
  6.     begin
  7.       repeat
  8.         if ((Arch.Name<>'.') and (Arch.Name<>'..')) then
  9.         begin
  10.           ....
  11.         end;
  12.       until FindNext(Arch)<>0;
  13.       FindClose(Arch);
  14.     end;
  15. end;

https://www.freepascal.org/docs-html/rtl/sysutils/findfirst.html
Lazarus 2.0.8 FPC 3.0.4 Linux Mint Mate 19.3
Zeos 7̶.̶2̶.̶6̶ 7.1.3a-stable - Sqlite 3.32.3 - LazReport

panosdk

  • New Member
  • *
  • Posts: 16
Re: Findfirst() problem
« Reply #4 on: December 11, 2021, 05:20:33 am »
Sorry I was wrong. FindFirst returns -1 if I add  faAnyFolder
and 0 if I only put faAnyFile and not faDirectory

It seems like its not finding any file and it only continues if it finds a folder. Btw I am using the SelectDirectoryDialog to get the path of the folder the user will pick. Here is the whole procedure code.

Code: Pascal  [Select][+][-]
  1. procedure Tform1.btn_batchClick(Sender: TObject);
  2.  
  3.   Const
  4.       FileFound = 0;
  5.       CharCR = Chr(13);
  6.       CharLF = Chr(10); //Windows ?30?
  7.       StringCRLF = CharCR + CharLF;
  8.       WildcardSearch = '*';
  9.  
  10. Var
  11.    SearchResult : TSearchRec;
  12.    //MoreFiles : Integer;
  13.    pathname:string;
  14.    first_file:string;
  15.    result:integer = 0;
  16.  
  17.  
  18. Begin
  19.  
  20. SelectDirectoryDialog1.execute;
  21. pathname:=SelectDirectoryDialog1.FileName;
  22.  
  23. If FindFirst (pathname + WildcardSearch, faAnyFile and not faDirectory, SearchResult) = FileFound Then
  24.    Begin
  25.    first_file:= SearchResult.Name;
  26.    While FindNext (SearchResult) = FileFound Do
  27.          Begin
  28.          
  29.          if (pos('jpg',searchresult.Name)<>0) or (pos('JPG',searchresult.Name)<>0) then
  30.          picture_counter :=picture_counter +1
  31.          else if (pos('png',searchresult.name)<>0) or (pos('PNG',searchresult.name)<>0) then
  32.          picture_counter :=picture_counter +1
  33.          else if (pos('bmp',searchresult.name)<>0) or (pos('BMP',searchresult.name)<>0) then
  34.          picture_counter:=picture_counter+1
  35.          else if (pos('gif',searchresult.name)<>0) or (pos('GIF',searchresult.name)<>0) then
  36.          picture_counter :=picture_counter+1
  37.          else
  38.             //do nothing
  39.          End;
  40.    {
  41.    if (pos('jpg',first_file)<>0) or (pos('JPG',first_file)<>0) then
  42.          picture_counter :=picture_counter +1
  43.          else if (pos('png',first_file)<>0) or (pos('PNG',first_file)<>0) then
  44.          picture_counter :=picture_counter +1
  45.          else if (pos('bmp',first_file)<>0) or (pos('BMP',first_file)<>0) then
  46.          picture_counter:=picture_counter+1
  47.          else if (pos('gif',first_file)<>0) or (pos('GIF',first_file)<>0) then
  48.          picture_counter :=picture_counter+1
  49.          else
  50.             //do nothing
  51.    End;
  52. FindClose (SearchResult);
  53. showmessage('Found ' + inttostr(picture_counter) + ' pictures in ' + pathname);
  54. end;                              

GAN

  • Sr. Member
  • ****
  • Posts: 370
Re: Findfirst() problem
« Reply #5 on: December 11, 2021, 05:29:45 am »
Try with the repeat until loop instead of while do.
Lazarus 2.0.8 FPC 3.0.4 Linux Mint Mate 19.3
Zeos 7̶.̶2̶.̶6̶ 7.1.3a-stable - Sqlite 3.32.3 - LazReport

Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: Findfirst() problem
« Reply #6 on: December 11, 2021, 05:57:55 am »
@panosdk

Can you please provide a compile-able short demo and maybe some sample data? Without a compile-able source code, most people can only guess but if we can run, debug and inspect into your source code, we can solve your problem - I believe - in just minutes. Simply providing some lines isn't very helpful, it won't run if I simply copy/paste them into my computer.

You can use:
Lazarus main menu > Project > Publish Project

or:
Create a new folder, copy and paste all the necessary files (sample data files) except: the binary (exe file), *.bak, lib and backup folders. Compress the folder and send the zip to the forum.

If you're not willing to publicize the whole project, you can provide a simplified version that still can show the issue.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Findfirst() problem
« Reply #7 on: December 11, 2021, 11:08:16 am »
Code: Pascal  [Select][+][-]
  1. SelectDirectoryDialog1.Execute;
  2. pathname:=SelectDirectoryDialog1.FileName;
  3. If FindFirst (pathname + WildcardSearch, (faAnyFile And Not faDirectory) , SearchResult) = FileFound Then
  4.    Begin
  5.    -some more code-

Not related to your question about FindFirst, but your code is flawed from the start.
You should only continue with the rest of the code if, and only if SelectDirectoryDialog1.Execute returns True.
So
Code: Pascal  [Select][+][-]
  1. if SelectDirectoryDialog1.Execute then
  2. begin
  3.   pathname:=SelectDirectoryDialog1.FileName;
  4.   If FindFirst (pathname + WildcardSearch, (faAnyFile And Not faDirectory) , SearchResult) = FileFound Then
  5.    Begin
  6.    -some more code-
  7. end;

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Findfirst() problem
« Reply #8 on: December 11, 2021, 11:12:30 am »
Sorry I was wrong. FindFirst returns -1 if I add  faAnyFolder

Never heard of faAnyFolder.

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Findfirst() problem
« Reply #9 on: December 11, 2021, 11:32:36 am »
Code: Pascal  [Select][+][-]
  1. procedure Tform1.btn_batchClick(Sender: TObject);
  2. ...
  3.          Begin
  4.          
  5.          if (pos('jpg',searchresult.Name)<>0) or (pos('JPG',searchresult.Name)<>0) then
  6.          picture_counter :=picture_counter +1
  7.  

And that piece of code of course also does NOT what you want it to do.
(Assuming you want to find pictures.)

It will increment the counter if the filename is e.g. 'this is not a jpg.docx'.
It will not incremet the counter for a filename like 'this is a picture.jPg'.

Why don't you simly use and extend the example program from official fpc documentation on findfirst?:
Code: Pascal  [Select][+][-]
  1. Uses SysUtils;
  2.  
  3. Var Info : TSearchRec;
  4.     Count : Longint;
  5.     Ext: String;
  6.     PathName: String;
  7.  
  8. Begin
  9.   Count:=0;
  10.   If FindFirst ('*',faAnyFile,Info)=0 then
  11.   begin
  12.     Repeat
  13.       With Info do
  14.       begin
  15.         If (Attr and faDirectory) <> faDirectory then
  16.         begin
  17.           Ext := UpperCase(ExtractFileExt(Name));
  18.           if (Ext = '.JPG') or (Ext = '.PNG') or (Ext = '.GIF') or (Ext = '.BMP') then
  19.             Inc(Count);
  20.         end;
  21.       end;
  22.     Until FindNext(info)<>0;
  23.     FindClose(Info);
  24.   end;
  25.   Writeln ('Finished search. Found ',Count,' matches');
  26. End.

B.t.w.
Given that you are using SelectDirectoryDialog, you are on Lazarus (not pure/plain fpc).
Why are you making your life so difficult when you already have available to you the FindAllFiles() procedure?
You can specify a list of masks ('*.jpg;*.bmp;*.png;*.gif'), wether or not the mask is case sensitive (you want that parameter to be False) and wether or not to also search subdirectories.

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: Findfirst() problem
« Reply #10 on: December 11, 2021, 04:36:41 pm »
Everyone has to have a version of their own !  :D

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.  
  3. Var
  4.   SR:TSearchRec;
  5.   R,C:Integer;
  6. begin
  7.   C:=0;
  8.   Stop := False;
  9.   R := FindFirst('C:\LazarusProjects\32bit\SSTv32\*.*',faArchive,SR);
  10.   While (Not LongBool(R))and(Not Stop) DO
  11.     Begin
  12.       IF Pos(UpperCase(ExtractFileExt(SR.Name)),'.JPG.PNG.GIF.BMP')<> 0 Then
  13.        begin
  14.         Inc(C);
  15.         Caption:=C.Tostring;
  16.        End;
  17.         Application.ProcessMessages;
  18.         R := FindNext(SR);
  19.     end;
  20.   FindCLose(Sr);
  21. end;                                
  22.  
The only true wisdom is knowing you know nothing

panosdk

  • New Member
  • *
  • Posts: 16
Re: Findfirst() problem
« Reply #11 on: December 11, 2021, 09:49:54 pm »
Thank you for the replies guys. I am a complete noob to delphi and lazarus so you will have to excuse me. I am trying to learn by doing things and not reading so much. Which is not the best way but I cannot find some good courses on delphi/lazarus.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: Findfirst() problem
« Reply #12 on: December 11, 2021, 09:55:41 pm »
Everyone has to have a version of their own !  :D

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.   [snip]
  3.   While (Not LongBool(R))and(Not Stop) DO
  4.     Begin
  5.       IF Pos(UpperCase(ExtractFileExt(SR.Name)),'.JPG.PNG.GIF.BMP')<> 0 Then
  6.        begin
  7.         Inc(C);
  8.   [/snip]                          
  9.  

And now 'foo.j' and 'foo.p' are also pictures?

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6131
Re: Findfirst() problem
« Reply #13 on: December 11, 2021, 10:47:25 pm »
Guess you can't make everyone happy  >:(

EDIT.
  modified a little;;

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. Var
  3.   SR:TSearchRec;
  4.   R,C:Integer;
  5. begin
  6.   C:=0;
  7.   Stop := False;
  8.   R := FindFirst('C:\LazarusProjects\32bit\SSTv32\*.*',faArchive,SR);
  9.   While (Not LongBool(R))and(Not Stop) DO
  10.     Begin
  11.       IF Pos(UpperCase(ExtractFileExt(SR.Name)+'!'),'.JPG!.GIF!.PNG!.BMP!')<>0  Then
  12.        begin
  13.         Inc(C);
  14.         Caption:=C.Tostring;
  15.        End;
  16.         Application.ProcessMessages;
  17.         R := FindNext(SR);
  18.     end;
  19.   FindCLose(Sr);
  20. end;                            
  21.  
« Last Edit: December 12, 2021, 02:07:29 am by jamie »
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018