Delphi - Állomány, alkönyvtár törlő komponens

forráskód letöltése
A mindennapi munka során gyakran keletkeznek olyan fájlok és könyvtárak melyekre csak átmenetileg volt szükségünk, illetve a saját programunk is létrehozhat ilyeneket. Miután ezekre már nincs szükségünk, csak feleslegesen foglalják a helyet, ezért törölnünk kellene azokat. Ebben a cikkben egy olyan komponenst mutatunk be, amely egy könyvtár megadott kiterjesztésű állományait, illetve könyvtárait törli. A mellékelt példaprogram megnyitása előtt a Remove.pas-ban lévő komponenst telepítenie kell a Delphi alá. Kipróbálás előtt ellenőrizzük a komponens Path property-ét és ha kell módosítsuk a benne lévő elérési útvonalat, hogy az a helyes könyvtárra mutasson.

A komponens Path property-jében kell megadni azt az alkönyvtárt, amiben a törlendő fájlok illetve alkönyvtárak vannak. A RemoveItems property-ben vannak felsorolva a törlendő fájlok kiterjesztései, valamint a törlendő alkönyvtárak nevei. A Question property azt adja meg, hogy a törlés előtt kérdezze-e meg a felhasználótól, hogy tényleg akarja-e törölni az állományokat és a könyvtárakat. A törlendő kiterjesztéseket és könyvtárneveket a RemoveItems property tartalmazza. A RemoveItems property elemeinek két további property-je van. Az egyik az Extension, ahol fájl kiterjesztést, a másik az Folder ahol könyvtárnevet kell megadnunk, egy elemnél egyszerre csak az egyiket! A kiterjesztést pont nélkül kell megadni (pl. "BAK"). Ha megadunk könyvtárneveket is, akkor arra figyelni kell, hogy az összes ilyen nevű könyvtár törölve lesz. Például ha a Path property értéke "C:\TEMP", és a "BIN" nevű könyvtárat szeretnénk törölni, akkor a "C:\TEMP\BIN", "C:\TEMP\AKARMI\BIN", stb. könyvtárak is törölve lesznek! Összetett elérési útvonalat (pl. "TEMP/SRC") a Folder property-ben nem lehet megadni!

A komponens szerkesztési időben is kipróbálható. Ehhez először be kell állítanunk a property-ket a megfelelő értékekre, majd a komponensen kattintva a jobb egérgombbal a megjelenő menüből az Execute menüpontot kiválasztva indíthatjuk a törlést.

A törlés az Execute eljárás meghívásával kezdődik. Ha a Question property értéke true, akkor rákérdez, hogy tényleg törölhet-e. Az üzenet szövege, és a dialógus ablak fejlécének felirata típusos konstansokban vannak eltárolva, így ezek tetszés szerint módosíthatók.
Ha indulhat a törlés, akkor meghívjuk a ScanDir eljárást a Path paraméterrel, ami a könyvtár nevét tartalmazza.
procedure TRemove.Execute;
var ok:boolean;
begin
  if FQuestion then begin
    ok:=Application.MessageBox(PCHAR(REMQ_TEXT), PCHAR(REMQ_CAPTION), MB_YESNO+MB_ICONWARNING)
       =IDYES;
  end else ok:=True;
  if ok then ScanDir(FPath);
end;
A ScanDir eljárás beolvassa a paraméterként megkapott könyvtár fájljait.

Ha a dir paraméter nem "\" karakterre végződik, akkor ezt pótolja.
  if dir[length(dir)]<>'\' then dir:=dir+'\';
A FindFirst függvénnyel beolvassuk az első fájl adatait. Ha a függvény visszatérési értéke 0, akkor a beolvasás sikeres volt.
  if FindFirst(dir+'*.*', faAnyFile, F)=0 then begin
Egy ciklust indítunk, ami addig tart, amíg van a könyvtárban beolvasható fájl.

Ha a beolvasott fájl egy könyvtár, akkor ellenőrizzük, hogy ponttal kezdődik-e. Ha igen, akkor nem foglalkozunk vele, ellenkező esetben meghívjuk a RemoveDir függvényt paraméterként átadva a beolvasott könyvtár nevét. A RemoveDir függvény ellenőrzi, hogy a könyvtárat törölni kell-e, és ha igen, akkor törli azt, majd true értékkel tér vissza. Ha a könyvtárat nem kell törölni, akkor rekurzívan meghívjuk a ScanDir eljárást paraméterként átadva a könyvtár nevét.
      if (F.Attr and faDirectory)>0 then begin
        if F.Name[1]<>'.' then begin
          if NOT RemoveDir(dir+F.Name) then ScanDir(dir+F.Name);
        end;
Ha a beolvasott fájl nem könyvtár, akkor meghívjuk a RemoveFile függvényt, ami ellenőrzi, hogy a fájl kiterjesztése a törlendő fájlkiterjesztések között megtalálható-e, és ha igen, akkor törli is a fájlt.
      end else begin
        RemoveFile(dir+F.Name);
      end;
A FindNext függvénnyel beolvassuk a következő fájl adatait mindaddig, amíg a függvény visszatérési értéke 0. Ellenkező esetben a FindClose függvénnyel lezárjuk a keresést.

Van tehát egy RemoveDir függvényünk és egy RemoveFile nevű eljárásunk. Először nézzük meg a RemoveDir függvényt. Ebben végigmegyünk az FRemoveItems property elemein, és megvizsgáljuk, hogy a paraméterként megkapott könyvtár a törlendő könyvtárak között van-e. Ha igen, akkor meghívjuk a DeleteDir eljárást és true értékkel térünk vissza, egyébként a visszatérési érték false lesz.

A RemoveFile hasonlóan működik, mint a RemoveDir. Itt is végigmegyünk az FRemoveItems property elemein, de itt azt vizsgáljuk, hogy a fájlnév kiterjesztése a törlendő fájlkiterjesztések között megtalálható-e. Ha igen, akkor töröljük a fájlt a DeleteFile függvénnyel.

A könyvtár törlése ennél valamivel bonyolultabb, hiszen csak olyan könyvtárat tudunk törölni, amely nem tartalmaz fájlokat, illetve alkönyvtárakat. Éppen ezért létre kell hoznunk egy olyan eljárást, ami rekurzívan végigmegy a könyvtár alkönyvtárain és fájljain, és mindet egyenként törli is. Ez az eljárás a DeleteDir. Ez hasonlóan a fenti módszerhez végigmegy a paraméterként megadott könyvtáron és törli annak fájljait, illetve miután a fájlokat törölte magát a könyvtárat is törli.
procedure TRemove.DeleteFolder;
var
  F:TSearchRec;
begin
  if dir[length(dir)]<>'\' then dir:=dir+'\';
  if FindFirst(dir+'*.*', faAnyFile, F)=0 then begin
    repeat
      if (F.Attr and faDirectory)>0 then begin
        if F.Name[1]<>'.' then DeleteFolder(dir+F.Name);
      end else begin
        DeleteFile(dir+F.Name);
      end;
    until FindNext(F)<>0;
    FindClose(F); RmDir(dir);
  end;
end;