Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



Share:
Notifications
Clear all

[Solved] Lazarus Pascal - Detect if directory has certain file types (cross platform, and optional subdirs)

2 Posts
1 Users
0 Reactions
21 Views
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2927
Topic starter  

For one of my applications I needed a function to determine if a directory, and optionally its sub directories, had at least one file with a certain file extension. So I wrote one myself, hopefully someone can use this.

FoundFiles := DirectoryHasTheseFiles(Dirname, '*.ext1,*ext2;', true);

aDir is a directory (regular filename would not be checked!).
SearchMask is your typical mask '*.ext1;*.ext2;*.ext3;'.
CheckSubDirs is a boolean to set if sub directories should be searched as well.

As soon as a matching file has been found, the search stops and exits with a positive outcome (true).
If no matching file was found, the result will be false.

Note: Uses sysutils unit.

  function DirectoryHasTheseFiles(aDir:string; SearchMask:string; checkSubDirs:boolean):boolean;
  var
    SearchRecResult: TSearchRec;
    FoundAFile: boolean;

    function ValidExtension:Boolean;
    begin
      Result := (pos('*'+ExtractFileExt(SearchRecResult.Name)+';', SearchMask)>0);
    end;

  begin
    SearchMask := SearchMask+';'; // in case the list doesn't end with a ";"
    FoundAFile := FindFirst(IncludeTrailingPathDelimiter(aDir) + '*', faAnyFile, SearchRecResult) = 0;
    Result     := False;

    while FoundAFile and not(Result) do
      begin
        // Found a matching extensions that is not a directory
        if not(DirectoryExists(IncludeTrailingPathDelimiter(aDir)+SearchRecResult.Name)) and ValidExtension then
          begin
            Result := true;
            break;
          end;

        // if checkSubDirs search subdirs are not . or ..
        if checkSubDirs and
           ( SearchRecResult.Name<>'.') and
           ( SearchRecResult.Name<>'..') and
           DirectoryExists(IncludeTrailingPathDelimiter(aDir)+SearchRecResult.Name) then
          begin
            if DirectoryHasTheseFiles(IncludeTrailingPathDelimiter(aDir)+SearchRecResult.Name, SearchMask, checkSubDirs) then
              begin
                Result := true;
                break;
              end;
          end;

        FoundAFile := FindNext(SearchRecResult)=0;
      end;

    FindClose(SearchRecResult);
  end;         

 

This topic was modified 9 hours ago 3 times by Hans

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 12 years ago
Posts: 2927
Topic starter  

For those wanting to use this with an OnDropFiles event:

procedure TForm1.FormDropFiles(Sender: TObject; const FileNames: array of string);
var
  Counter:integer;
  hasSuitableFiles:boolean;
  // ...
begin
  // check if suitable files are included 
  hasSuitableFiles := false;
  for Counter:=0 to Length(FileNames)-1 do
    if DirectoryExists(Filenames[Counter]) and DirectoryHasTheseFiles(Filenames[Counter],'*.ext1;*.ext2;',true) then
      begin
        hasSuitableFiles := true;
        break;
      end
    else if (pos('*'+ExtractFileExt(Filenames[Counter])+';', '*.ext1;*.ext2;')>0) then
      begin
        hasSuitableFiles:=true;
        break;
      end;

  // no suitable files found, exit ...
  if not hasSuitableFiles then exit;   

  // do your thing
end;

   
ReplyQuote
Share: