Difference between revisions of "FindAllFiles"

From Lazarus wiki
Jump to navigationJump to search
(Remove LazFileUtils)
(Sections about memory leaks, LCLBase -- to make the topics clear)
 
(8 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
{{FindAllFiles}}
 
{{FindAllFiles}}
  
[[Unit]]:  
+
[[Unit]]: Lazarus [[fileutil]].
Lazarus [[FileUtils]]
+
 
 +
To enable FileUtil in your project, please add LazUtils into required packages. Follow these steps:
 +
 
 +
* Go to ''Lazarus IDE Menu'' > ''Project'' > ''Project Inspector''
 +
* In the ''Project Inspector'' dialog window, click ''Add'' > ''New Requirement''
 +
* In the ''New Requirement'' dialog window, find ''LazUtils'' package then click OK.
  
 
See also:
 
See also:
* http://lazarus-ccr.sourceforge.net/docs/lcl/fileutil/findallfiles.html
 
* http://lazarus-ccr.sourceforge.net/docs/lcl/fileutil/tfilesearcher.html
 
  
<syntaxhighlight>
+
* https://lazarus-ccr.sourceforge.io/docs/lazutils/fileutil/findallfiles.html
 +
* https://lazarus-ccr.sourceforge.io/docs/lazutils/fileutil/tfilesearcher.html
 +
 
 +
<syntaxhighlight lang="pascal">
 
procedure FindAllFiles(AList: TStrings; const SearchPath: String;
 
procedure FindAllFiles(AList: TStrings; const SearchPath: String;
 
   SearchMask: String = ''; SearchSubDirs: Boolean = True; DirAttr: Word = faDirectory);  
 
   SearchMask: String = ''; SearchSubDirs: Boolean = True; DirAttr: Word = faDirectory);  
Line 16: Line 22:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
'''FindAllFiles''' looks for files matching the searchmask in the SearchPath directory and if specified its children and populates a [[TStrings|stringlist]] with the resulting filenames.
+
'''FindAllFiles''' looks for files matching the SearchMask in the SearchPath directory and, if specified, its subdirectories, and populates a [[TStrings|stringlist]] with the resulting filenames.
  
 
The mask can be a single mask like you can use with the FindFirst/FindNext functions,
 
The mask can be a single mask like you can use with the FindFirst/FindNext functions,
 
or it can consist of a list of masks, separated by a [[Semicolon|semicolon (;)]].<br>
 
or it can consist of a list of masks, separated by a [[Semicolon|semicolon (;)]].<br>
 
Spaces in the mask are treated as literals.
 
Spaces in the mask are treated as literals.
 +
 +
Parameter DirAttr is int file attribute: if file-system item has this attribute(s), it is considered as a directory. It can be faDirectory, faSymLink, (faDirectory+faSymLink) or maybe another bits can be used.
  
 
There are two overloaded versions of this routine. The first one is a '''[[Procedure|procedure]]''' and assumes that the receiving stringlist already has been created.
 
There are two overloaded versions of this routine. The first one is a '''[[Procedure|procedure]]''' and assumes that the receiving stringlist already has been created.
 
The second one is a '''[[Function|function]]''' which creates the stringlist internally and returns it as a function result. In both cases the stringlist must be destroyed by the calling procedure.
 
The second one is a '''[[Function|function]]''' which creates the stringlist internally and returns it as a function result. In both cases the stringlist must be destroyed by the calling procedure.
  
'''Example:'''
+
== Example ==
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal">
 
uses  
 
uses  
   ..., FileUtils, ...
+
   ..., FileUtil, ...
 
var
 
var
 
   PascalFiles: TStringList;
 
   PascalFiles: TStringList;
Line 52: Line 61:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
'''IMPORTANT NOTE:'''
+
== Watch out for memory leaks, esp. with the <code>FindAllFiles</code> function ==
The ''function'' "FindAllFiles" creates the stringlist internally. This may look very convenient at first sight, but it is very easy to create '''memory leaks''' that way:
 
  
<syntaxhighlight>
+
The ''function'' <code>FindAllFiles</code> creates the <code>TStringList</code>. This is convenient, but beware of memory leaks.
  // DON'T EVER DO THIS !!!! - There is no way to destroy the stringlist created by FindAllFiles.
+
 
  Listbox1.Items.Assign(FindAllFiles(LazarusDirectory, '*.pas;*.pp;*.p;*.inc', true);
+
<syntaxhighlight lang="pascal">
 +
// DON'T DO THIS - the line below means that TStringList created by `FindAllFiles` is never freed.
 +
Listbox1.Items.Assign(FindAllFiles(LazarusDirectory, '*.pas;*.pp;*.p;*.inc', true));
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Fix it to this:
 +
 +
<syntaxhighlight lang="pascal">
 +
List := FindAllFiles(LazarusDirectory, '*.pas;*.pp;*.p;*.inc', true);
 +
try
 +
  Listbox1.Items.Assign(List);
 +
finally
 +
  List.Free;
 +
end;
 +
</syntaxhighlight>
 +
 +
== This unit is part of LCLBase ==
 +
  
 
{{Note|If you want to use this function in command line programs, add a project requirement for ''LCLBase'', which will not pull in the entire LCL}}
 
{{Note|If you want to use this function in command line programs, add a project requirement for ''LCLBase'', which will not pull in the entire LCL}}

Latest revision as of 15:21, 26 April 2024

English (en) español (es) suomi (fi) français (fr) polski (pl) русский (ru)

Unit: Lazarus fileutil.

To enable FileUtil in your project, please add LazUtils into required packages. Follow these steps:

  • Go to Lazarus IDE Menu > Project > Project Inspector
  • In the Project Inspector dialog window, click Add > New Requirement
  • In the New Requirement dialog window, find LazUtils package then click OK.

See also:

procedure FindAllFiles(AList: TStrings; const SearchPath: String;
  SearchMask: String = ''; SearchSubDirs: Boolean = True; DirAttr: Word = faDirectory); 

function FindAllFiles(const SearchPath: String; SearchMask: String = '';
  SearchSubDirs: Boolean = True): TStringList;

FindAllFiles looks for files matching the SearchMask in the SearchPath directory and, if specified, its subdirectories, and populates a stringlist with the resulting filenames.

The mask can be a single mask like you can use with the FindFirst/FindNext functions, or it can consist of a list of masks, separated by a semicolon (;).
Spaces in the mask are treated as literals.

Parameter DirAttr is int file attribute: if file-system item has this attribute(s), it is considered as a directory. It can be faDirectory, faSymLink, (faDirectory+faSymLink) or maybe another bits can be used.

There are two overloaded versions of this routine. The first one is a procedure and assumes that the receiving stringlist already has been created. The second one is a function which creates the stringlist internally and returns it as a function result. In both cases the stringlist must be destroyed by the calling procedure.

Example

uses 
  ..., FileUtil, ...
var
  PascalFiles: TStringList;
begin
  PascalFiles := TStringList.Create;
  try
    FindAllFiles(PascalFiles, LazarusDirectory, '*.pas;*.pp;*.p;*.inc', true); //find e.g. all pascal sourcefiles
    ShowMessage(Format('Found %d Pascal source files', [PascalFiles.Count]));
  finally
    PascalFiles.Free;
  end;

// or

begin
  //No need to create the stringlist; the function does that for you
  PascalFiles := FindAllFiles(LazarusDirectory, '*.pas;*.pp;*.p;*.inc', true); //find e.g. all pascal sourcefiles
  try
    ShowMessage(Format('Found %d Pascal source files', [PascalFiles.Count]));
  finally
    PascalFiles.Free;
  end;

Watch out for memory leaks, esp. with the FindAllFiles function

The function FindAllFiles creates the TStringList. This is convenient, but beware of memory leaks.

// DON'T DO THIS - the line below means that TStringList created by `FindAllFiles` is never freed.
Listbox1.Items.Assign(FindAllFiles(LazarusDirectory, '*.pas;*.pp;*.p;*.inc', true));

Fix it to this:

List := FindAllFiles(LazarusDirectory, '*.pas;*.pp;*.p;*.inc', true);
try
  Listbox1.Items.Assign(List);
finally 
  List.Free;
end;

This unit is part of LCLBase

Light bulb  Note: If you want to use this function in command line programs, add a project requirement for LCLBase, which will not pull in the entire LCL