Mega Code Archive

 
Categories / Delphi / Files
 

Traverse files in a folder structure

Title: Traverse files in a folder structure Question: How do I scan through all of the files on a drive or in a folder? Only tested in Delphi 7. Answer: Create a unit with the code here to define the object. unit IGSUnit_DriveScan; interface uses SysUtils; {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} { OBJECT - TDriveScan } { PURPOSE - Provides an easy way to scan the files in a folder structure, } { accessing one at a time. Automatically traverses the directory } { structure } { USAGE - Define a variable of type TDriveScan eg Scan: TDriveScan } { Create an instance of TDriveScan eg Scan := TDriveScan.Create; } { Start the scan with ScanStart, this required a starting path and } { gets the first file eg Scan.ScanStart('c:\windows\') } { Access the details of the file using SearchRec } { eg Scan.SearchRec.Name } { Get the next file eg Scan.ScanNext } { Free the object eg Scan.Free } { BY - Ian Smith, 2004 } {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} type TDriveScan = class(TObject) private FStartDir: string; FSearchRec: TSearchRec; FSearchRecs: array of TSearchRec; FValidRes: integer; FTreeLevel: integer; function ScanPath: string; procedure DrillDown; public constructor Create; procedure ScanStart(StartDir: string); procedure ScanNext; property SearchRec: TSearchRec read FSearchRec; property ValidRes: integer read FValidRes; end; implementation {------------------------------------------------------------------------------} procedure TDriveScan.DrillDown; begin if FSearchRecs[FTreeLevel].Name[1] '.' then if (FSearchRecs[FTreeLevel].Attr and faDirectory 0) then begin SetLength(FSearchRecs, FTreeLevel + 2); FValidRes := FindFirst(ScanPath, faAnyFile, FSearchRecs[FTreeLevel + 1]); if FValidRes = 0 then inc(FTreeLevel); end; FValidRes := FindNext(FSearchRecs[FTreeLevel]); while (FSearchRecs[FTreeLevel].Name[1] = '.') and (FValidRes = 0) do FValidRes := FindNext(FSearchRecs[FTreeLevel]); FSearchRec := FSearchRecs[FTreeLevel]; end; {------------------------------------------------------------------------------} function TDriveScan.ScanPath: string; var I: integer; begin Result := FStartDir; if FTreeLevel -1 then begin for I := 0 to FTreeLevel do begin Result := Result + FSearchRecs[I].Name + '\'; end; Result := Result + '*.*'; end; end; {------------------------------------------------------------------------------} procedure TDriveScan.ScanNext; begin if not ((FSearchRecs[FTreeLevel].Attr and faDirectory 0) and (FValidRes = 0)) then FValidRes := FindNext(FSearchRecs[FTreeLevel]) else while (FSearchRecs[FTreeLevel].Attr and faDirectory 0) and (FValidRes = 0) do Drilldown; FSearchRec := FSearchRecs[FTreeLevel]; while (FValidRes 0) and (FTreeLevel 0) do begin dec(FTreeLevel); FValidRes := FindNext(FSearchRecs[FTreeLevel]); while (FSearchRecs[FTreeLevel].Name[1] = '.') and (FValidRes = 0) do FValidRes := FindNext(FSearchRecs[FTreeLevel]); while (FSearchRecs[FTreeLevel].Attr and faDirectory 0) and (FValidRes = 0) do Drilldown; end; end; {------------------------------------------------------------------------------} procedure TDriveScan.ScanStart(StartDir: string); begin SetLength(FSearchRecs, 1); FValidRes := FindFirst(StartDir + '*.*', faAnyFile, FSearchRecs[0]); if FValidRes = 0 then begin FSearchRec := FSearchRecs[0]; FStartDir := StartDir; FTreeLevel := 0; end; if FSearchRecs[FTreeLevel].Name[1] = '.' then ScanNext; end; {------------------------------------------------------------------------------} constructor TDriveScan.Create; begin inherited create; FTreeLevel := -1; end; end. EXAMPLE OF USE unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses IGSUnit_DriveScan; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Scan: TDriveScan; FileCount: integer; begin Scan := TDriveScan.Create; FileCount := 0; Scan.ScanStart('c:\'); while Scan.ValidRes = 0 do begin Memo1.Lines.Add(Scan.SearchRec.Name); Scan.ScanNext; inc(FileCount); end; label1.Caption := inttostr(FileCount); end; end. This shows a new project with a memo, label and button added to the form. You need to add the TDriveScan's unit to the project and then add it to uses. Add the code under the buttonclick event. This example scans all the files on the C drive and lists them in the memo. When the scan finishes the number of files is shown in the label. Note that folders are included in the list and the count. I made this object to scan through a drive one item at a time so I could stop and start when I wanted, not bound to a recursive loop. It isn't the fastest way to scan a drive but it is convenient and keeps the main code clean. Feedback welcome.