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


Delete an entire directory tree using recursionFormat this article printer-friendly!Bookmark function is only available for registered users!
A pascal unit containing procedures for deleting a tree
Product:
Delphi all versions
Category:
Files Operation
Skill Level:
Scoring:
Last Update:
02/24/2000
Search Keys:
delphi delphi3000 article borland vcl code-snippet RemoveTree Delete Tree
Times Scored:
5
Visits:
6143
Uploader: Den Bedard
Company: DTX Technologies, LLC
Reference: N/A
 
Question/Problem/Abstract:
How do I use recursion to delete a directory and all of its subirectories and files?
Answer:



{Use this unit to remove an entire directory tree
using recursion}


unit DeleTree;

interface
uses Classes, FileCtrl, SysUtils;

procedure RemoveTree(path: string);
procedure RemoveDirectory(path: string);
procedure GetFileList(FileSpec: string;
                       NamesOnly: Boolean;
                       var FileList: TStringList);
procedure GetSubDirList(DirRoot: string;
                       NamesOnly: Boolean;
                       var SubDirList: TStringList);
function BackSlash(FileSpec: string): string;
function NoBackSlash(FileSpec: string): string;

implementation

{--------------------------------------------------------}
{this procedure will remove an entire directory tree}
procedure RemoveTree(path: string);
var
  SubDirList: TStringList;
  FileList: TStringList;
  i: integer;
begin
  SubDirList := TStringList.Create;
  GetSubDirList(path,False,SubDirList);

  {if this tree has more than one sub-directory
   then recurse to remove each sub-directory tree}
  if SubDirList.Count>0 then
  begin
    for i := 0 to SubDirList.Count-1 do
    begin
      RemoveTree(SubDirList[i]);
    end;
  end;
  SubDirList.free;

  {if we are here then all sub-directory trees have been
   removed, or there were none. So we only need to
   delete all the files}
  FileList := TStringList.Create;
  GetFileList(BackSlash(path)+'*.*',False,FileList);
  for i := 0 to FileList.Count-1 do
  begin
    DeleteFile(PChar(FileList[i]));
  end;
  FileList.Free;
  RemoveDirectory(path);
end;


{--------------------------------------------------------}
{this procedure will remove a directory if it exists}
procedure RemoveDirectory(path: string);
var
  Dir: string;
begin
  {remove the final back-slash if one exists}
  Dir := NoBackSlash(path);

  if DirectoryExists(Dir) then RmDir(Dir);
end;

{--------------------------------------------------------}
{this procedure will fill a StringList with the names of
all files matching the FileSpec. If NamesOnly is true
then the path will not be included}
procedure GetFileList(FileSpec: string;
                      NamesOnly: Boolean;
                      var FileList: TStringList);
var
  SR: TSearchRec;
  DosError: integer;
begin
  FileList.Clear;

  DosError := FindFirst(FileSpec, faAnyFile-faDirectory, SR);
  while DosError=0 do
  begin
    if NamesOnly
      then FileList.Add(SR.Name)
      else FileList.Add(ExtractFilePath(FileSpec)+SR.Name);
    DosError := FindNext(SR);
  end;
end;

{--------------------------------------------------------}
{this procedure will fill a StringList with the names of
all sub-directories in the directory specified by DirRoot.
If NamesOnly is true then only the deepest directory
names will be included}
procedure GetSubDirList(DirRoot: string;
                        NamesOnly: Boolean;
                        var SubDirList: TStringList);
var
  SR: TSearchRec;
  DosError: integer;
  Root: string;
begin
  SubDirList.Clear;

  {add a final backslash if none exists}
  Root := BackSlash(DirRoot);

  {use FindFirst/FindNext to return only directories}
  DosError := FindFirst(Root+'*.*', faDirectory, SR);
  while DosError=0 do
  begin
    {don't include the directories . and ..}
    if pos('.',SR.Name)<>1 then
    begin
      if SR.Attr=faDirectory then
      begin
        if NamesOnly
          then SubDirList.Add(SR.Name)
          else SubDirList.Add(Root+SR.Name);
      end;
    end;
    DosError := FindNext(SR);
  end;
end;

{--------------------------------------------------------}
{Add a backslash if none exists}
function BackSlash(FileSpec: string): string;
begin
  if (FileSpec[length(FileSpec)]<>'\')
     then Result := FileSpec+'\'
     else Result := FileSpec;
end;

{Remove a backslash if one exists}
function NoBackSlash(FileSpec: string): string;
begin
  if (FileSpec[length(FileSpec)]='\')
     then Result := Copy(FileSpec,1,length(FileSpec)-1)
     else Result := FileSpec;
end;

end.





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
DeleteRecurse
    Oleg Astakhov (Feb 13 2005 7:40PM)

Thank you, Frederic, works great...would be cool though if it removed the readonly attributes too, because it does not delete the files and hence directories which have this attribute on.
Respond

Compact but readable deleteRecurse...?
    Frederic WOEHL (Aug 31 2000 10:06AM)

What about this compact code ?

procedure DeleteRecurse( src : String ) ;
var
  sts : Integer ;
  SR: TSearchRec;
begin
  sts := FindFirst( src + '*.*' , faDirectory , SR ) ;
  if sts = 0 then
  begin
    if ( SR.Name <> '.' ) and ( SR.Name <> '..' ) then
    begin
      if SR.Attr = faDirectory then
      begin
          DeleteRecurse( src + SR.Name + '\' ) ;
          {$I-}RmDir( src + SR.Name ) ;{$I+}
      end
      else
        DeleteFile( src + SR.Name ) ;
    end ;
    while FindNext( SR ) = 0 do
    if ( SR.Name <> '.' ) and ( SR.Name <> '..' ) then
    begin
      if SR.Attr = faDirectory then
      begin
        DeleteRecurse( src + SR.Name + '\' ) ;
        {$I-}RmDir( src + SR.Name ) ;{$I+}
      end
      else
        DeleteFile( src + SR.Name ) ;
    end ;
    FindClose( SR ) ;
  end ;
end ;

FRED

Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
M. Kleiner
 
   














 







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