delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
500 Users Online NOW
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi



Loremo - the 1.5 liter car coming in 2009




Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (3)


File & directory iterator Format this article printer-friendly!Bookmark function is only available for registered users!
Using a visitor pattern for iterating files and directories
Product:
Delphi all versions
Category:
Algorithm
Skill Level:
Scoring:
Last Update:
06/09/2004
Search Keys:
delphi delphi3000 article borland vcl code-snippet visitor pattern directory scan findfirst findnext files
Times Scored:
1
Visits:
1601
Uploader: Matt Harrison
Company:
Reference: lummie.co.uk
 
Question/Problem/Abstract:
The visitor pattern comes in very useful when requiring code to iterate directories. The pattern provides an object that calls back to a method that has been assigned to it for each element it iterates through. In this case it is a simple delphi event and we are iterating thorught directories and files. To use, simply create an instance of the TFileIterator object, assign it a callback method, then call exceute passing in the directory to scan, a file spec e.g. *.txt for all .txt files and a either fitSingleDirectory or fitIncludeSubDirectories to choose to scan just he specified directory or all directories. Your method will be called for every file that matches the criteria, passign the directory the iterator is currently processed, and the TSearchrec for the file it is currenlty on. If you want your call back to be called for directories as well then rem out the directory attribute check around the call to the callback. (line 70ish)

Answer:



{*
   Generic File Iterator unit (c) Matt Harrison 2004 visit lummie.co.uk.
   This unit provides an iterator methods and a standard callback event to
   allow quick iteration of files in directories.
   Create an instance, assign a callback event and call execute.
   NOTE : As the object is interfaced (and therefore referenced counted) you do not need to free it.

   If the callback returns true at any point the iterator will exit and exceute will return true.
   This allows itterations to be cancelled.

   e.g.

   FI := TFileIterator.create;
   FI.CallBack := MyCallBackEvent;
   Quitted := FI.execute('C:\windows','*.*',  fitSingleDirectory);
*}
unit FileIterater;

interface

uses
  classes, sysutils;

type
  TFileIteratorCallBackEvent = function (Directory : string; FoundFile : TSearchRec) : boolean of object;

  TFileIteratorType = (fitSingleDirectory, fitIncludeSubDirectories);

  TFileIterator = class(TInterfacedObject)
  private
    FCallback: TFileIteratorCallBackEvent;
  public
    procedure AfterConstruction; override;
    function Execute(Directory : string; FileSpec : string; ExecuteType : TFileIteratorType) : boolean;
    property Callback : TFileIteratorCallBackEvent read FCallback write FCallback;
  end;


implementation



{ TFileIterator }

procedure TFileIterator.AfterConstruction;
begin
  inherited;
  FCallback := nil;
end;

function TFileIterator.Execute(Directory : string; FileSpec : string; ExecuteType : TFileIteratorType) : boolean;

  procedure ProcessDir(Directory, FileSpec : string; ExecuteType : TFileIteratorType; var QuitFlag : boolean);
  var
    sr : TSearchRec;
  begin
    if ExecuteType = fitIncludeSubDirectories then
    begin
      // process sub directories
      if FindFirst(Directory + '*.*', faAnyFile, sr) = 0 then
      begin
        repeat
          if (sr.Attr and faDirectory = faDirectory) and (sr.Name <> '.') and (sr.Name <> '..') then // ignore . and ..
          begin
            ProcessDir(IncludeTrailingPathDelimiter(Directory + sr.name),FileSpec, ExecuteType, QuitFlag);
          end;
        until QuitFlag or (FindNext(sr) <> 0);
        FindClose(sr);
      end;
    end;


    if not QuitFlag and (FindFirst(Directory + FileSpec, faAnyFile, sr) = 0) then
    begin
      repeat
        if (sr.Attr and faDirectory = 0) and (sr.Name <> '.') and (sr.Name <> '..') then
        begin
          QuitFlag := CallBack(Directory,sr);
          if QuitFlag then break;
        end;
      until FindNext(sr) <> 0;
      FindClose(sr);
    end;
  end;

begin
  result := false;
  if not assigned(Callback) then raise exception.create('Execute called on TFileIterator with out assigning a callback');
  if not DirectoryExists(IncludeTrailingPathDelimiter(Directory)) then raise exception.create('Invlaid directory specified');

  ProcessDir(IncludeTrailingPathDelimiter(Directory),FileSpec, ExecuteType, result);
end;

end.





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
Added option to cancel iterations
    Matt Harrison (Jun 9 2004 1:22PM)

I have just updated the article to allow cancellations of the iterator by seting the return value of the callback to true.
Respond

nice
    Eber Irigoyen (Jun 9 2004 12:06AM)

simple and useful little class
Respond

RE: nice
Matt Harrison (Jun 9 2004 10:09PM)

Thanks for the feedback.
Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
S. Kucherov
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)