Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
462 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







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 (2)


Traverse files in a folder structureFormat this article printer-friendly!Bookmark function is only available for registered users!
An object for providing an easy way to traverse a folder structure.
Product:
Delphi 7.x (or higher)
Category:
Files Operation
Skill Level:
Scoring:
Last Update:
07/20/2004
Search Keys:
delphi delphi3000 article borland vcl code-snippet scan traverse folder directory files object TSearchRec
Times Scored:
1
Visits:
1271
Uploader: Ian Smith
Company:
Reference: N/A
 
Question/Problem/Abstract:
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.







Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
NLDFileSearch
    Jos Visser (Apr 26 2005 7:18PM)

http://www.nldelphi.com/Forum/showthread.php?t=5908
Respond

Think Recursive - Less code
    Bjarne Winkler (Jul 20 2004 5:50PM)

Function SearchTree32(slFileList: TStringList; sFolder, sFile: String; bFirstLevel: Boolean): String;
Var
  SR: TSearchRec;
  sOldDir: String;
  iDosError: Integer;
  bDone: Boolean;


Begin
  bDone := False;
  Result := '';
  If DirectoryExists(sFolder) Then
  Begin
    GetDir(0, sOldDir);
    ChDir(sFolder);
    { Find first file match spec }
    iDosError := SysUtils.FindFirst(sfile, 0, SR);
    { Find all files in the directory matching spec }
    While (iDosError = 0) And (Not bDone) Do
    Begin
      Try
        slFileList.Add(sFolder + SR.Name);
        Application.ProcessMessages;
      Except
        { If List box gets full ... }
        On EOutOfResources Do
        Begin
          { Show Message }
          ShowMessage('Resource Error');
          { Raise Abort exception to quit procedure }
          Abort;
        End;
      End;
      Application.ProcessMessages;
      iDosError := SysUtils.FindNext(SR);
    End;
    SysUtils.FindClose(SR);
    { Find first sub-directory in this directory }
    iDosError := SysUtils.FindFirst ('*.*', faDirectory, SR);
    { Find all sub-directory in this directory }
    While (iDosError = 0) And (Not bDone) And (Not bFirstLevel) Do
    Begin
      If (((SR.Attr And faDirectory) = faDirectory) And
          (SR.Name <> '.') And (SR.Name <> '..')) Then
      Begin
        { Change to the sub derectory }
        ChDir(SR.Name);
        { Recurse }
        Result := SearchTree32(slFileList, sFolder + SR.Name, sFile, bFirstLevel);
        { Drop back to parent directory }
        ChDir('..');
      End;
      Application.ProcessMessages;
      iDosError := SysUtils.FindNext(SR);
    End;
    SysUtils.FindClose(SR);
    ChDir(sOldDir);
  End;
End;

Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
M. Maes
 
   














 







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