Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Ordner nicht leer (https://www.delphipraxis.net/204816-ordner-nicht-leer.html)

kagi3624 2. Jul 2020 09:49

Ordner nicht leer
 
Hallo, ich brauche eine Funktion, die einen Ordner darauf prüft ob er Dateien hat. Also wenn er andere Ordner beinhaltet, soll die Funktion false zurückgeben. Darauf hin habe ich diese funktion hier gefunden.

Code:
//returns true if a given directory is empty, false otherwise
function IsDirectoryEmpty(const directory : string) : boolean;
var
   searchRec :TSearchRec;
begin
   try
    result := (FindFirst(directory+'\*.*', faAnyFile, searchRec) = 0) AND
              (FindNext(searchRec) = 0) AND
              (FindNext(searchRec) 0) ;
   finally
     FindClose(searchRec) ;
   end;
end;
http://delphi.cjcsoft.net/viewthread.php?tid=46131

aber mein delphi 6 kann es nicht kompilieren, es sagt (FindNext(searchRec) 0) da fehlt ein semikolon??

KodeZwerg 2. Jul 2020 09:58

AW: Ordner nicht leer
 
Vor der "0" fehlt "<>".

Hier ein , finde ich, besserer Vorschlag:

Delphi-Quellcode:
// Diese Funktion gibt true zurück, falls Directory ein leeres Verzeichnis ist.
// This function returns true if Directory is an empty directory.

function DirectoryIsEmpty(Directory: string): Boolean;
var
  SR: TSearchRec;
  i: Integer;
begin
  Result := False;
  FindFirst(IncludeTrailingPathDelimiter(Directory) + '*', faAnyFile, SR);
  for i := 1 to 2 do
    if (SR.Name = '.') or (SR.Name = '..') then
      Result := FindNext(SR) <> 0;
  FindClose(SR);
end;


// Beispiel:
// Example:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if DirectoryIsEmpty('C:\test') then
    Label1.Caption := 'empty'
  else
    Label1.Caption := 'not empty';
end;

kagi3624 2. Jul 2020 10:09

AW: Ordner nicht leer
 
Hallo KodeZwerg,

leider bekomme ich "nicht leer", also false, wenn in dem Ordner andere Ordner drin sind.

KodeZwerg 2. Jul 2020 10:22

AW: Ordner nicht leer
 
Wenn Unterverzeichnisse enthalten sind, ist das Haupt-Verzeichniss nicht leer, also ist Dein beschriebener Rückgabewert korrekt.
Man kann diese Funktion erweitern indem man, das muss dann leider sein, noch alle gefundendene Elemente auf sein Attribut abgleicht. (dauert halt länger)

Nur hier im Editor schnell mal was zusammengepopelt.... ungetestet...

Delphi-Quellcode:
function CheckIfFilesInPath(const Path: string): Boolean;
var
  SR: TSearchRec;
begin
  Result := False;
  if FindFirst(Path + '*.*', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
        Result := True;
        Break;
      end;
    until FindNext(SR) <> 0;
    FindClose(SR);
  end;
end;

So könnte was draus werden... teste mal und viel glück :-)

himitsu 2. Jul 2020 10:23

AW: Ordner nicht leer
 
Da fehlt ein
Delphi-Quellcode:
=
.
Tipp: Vergleich es mal mit der Zeile darüber. :zwinker:


Allerdings ist das etwas wage, denn die Funktion geht "blind" davon aus dass es . und .. gibt, also ab mindestens 3 "Einträgen" existiert mindestens eine Datei (könnte aber auch ein Verzeichnis sein).

Besser ist es in einer "normalen" suchschleife durchzulaufen,
vor Variable(n) auf False zu setzen,
die Dateien . und .. zu ignorieren,
und dann jeweils die Attribute zu prüfen (Datei oder Verzeichnis) und entsprechend die Variable(n) auf True zu setzen.
Ist/Sind die Variable(n) auf True, kann die Schleife vorzeitig abgebrochen werden. (Das Ergebnis steht ja schon fest)

[edit] siehe KodeZwerg

Andreas13 2. Jul 2020 10:31

AW: Ordner nicht leer
 
Hallo,
es ist ratsam, anstelle von
Delphi-Quellcode:
FindClose(SR);
einen qualifizierten Bezeichner
Delphi-Quellcode:
System.SysUtils.FindClose(SR);
zu verwenden, weil es u. U. Konflikt geben kann mit der gleichnamigen Procedure
Delphi-Quellcode:
WinAPI.Windows.FindClose(SR);
, die allerdings einen anderen Datentyp erwartet.
Gruß, Andreas

kagi3624 2. Jul 2020 10:44

AW: Ordner nicht leer
 
Ist es gut so?

Code:
function TForm1.CheckIfFilesInPath(const Path: string): Boolean;
var
  MySearch: TSearchRec;
  FindResult: Integer;
begin
  result := false;
  FindResult:=FindFirst(Path+'\*.*', faAnyFile, MySearch);
  while (FindResult = 0) do
  begin
    if (MySearch.Name<>'.') and (MySearch.Name<>'..') and (MySearch.Attr <> faDirectory) then begin
      result := true;
      break;
    end;

    FindResult := FindNext(MySearch);
  end;
  FindClose(MySearch);
end;
@Andreas13
das konnte ich so nicht kompilieren, ich bekomme den Fehler
Code:
[Fehler] trash.pas(213): Undefinierter Bezeichner: 'SysUtils'
das habe ich bei den Uses aber angebunden. Vielleicht liegt es aber an meinem uralten Delphi 6

Andreas13 2. Jul 2020 10:48

AW: Ordner nicht leer
 
Kein Problem: Wahrscheinlich hat Delphi 6 auch noch kein WinAPI.Windows, so daß es dort (noch) keinen Konflikt geben kann.
Andreas

DeddyH 2. Jul 2020 10:53

AW: Ordner nicht leer
 
Anderer Vorschlag:
Delphi-Quellcode:
function DirContainsFiles(const Dirname: string): Boolean;
var
  Rec: TSearchRec;
  SearchPattern: string;
begin
  Result := false;
  SearchPattern := IncludeTrailingBackslash(Dirname) + '*.*';
  if FindFirst(SearchPattern, faAnyFile, Rec) = 0 then
    try
      repeat
        if Rec.Attr and faDirectory = 0 then
          Result := true;
      until (FindNext(Rec) <> 0) or Result;
    finally
      SysUtils.FindClose(Rec);
    end;
end;

kagi3624 2. Jul 2020 11:04

AW: Ordner nicht leer
 
Hallo Deddyh! Könntest du bitte die Zeile hier erklären`?

Code:
if Rec.Attr and faDirectory = 0 then

DeddyH 2. Jul 2020 11:55

AW: Ordner nicht leer
 
Damit wird geprüft, ob die Bitmaske der Dateiattribute das Flag faDirectory enthält. Wenn ja, ist es ein Verzeichnis.

himitsu 2. Jul 2020 11:56

AW: Ordner nicht leer
 
in Rec ist eine Datei (Verzeichniss-Attribut ist nicht gesetzt)

kagi3624 2. Jul 2020 12:14

AW: Ordner nicht leer
 
Also lese ich das so richtig? Rec.Attr ist ein Integer und nicht null und faDirectory ist aber gleich null, dann ist es ein Ordner? Also kann man generell die Konstanten der FindFirt Funktion mit = 0 abfragen?

KodeZwerg 2. Jul 2020 12:17

AW: Ordner nicht leer
 
Zitat:

Zitat von kagi3624 (Beitrag 1468720)
Also lese ich das so richtig? Rec.Attr ist ein Integer und nicht null und faDirectory ist aber gleich null, dann ist es ein Ordner? Also kann man generell die Konstanten der FindFirt Funktion mit = 0 abfragen?

kurz und knapp, nein, weil .... ->
Zitat:

Zitat von DeddyH (Beitrag 1468718)
Damit wird geprüft, ob die Bitmaske der Dateiattribute das Flag faDirectory enthält. Wenn ja, ist es ein Verzeichnis.


einfach auf 0 prüfen ist der falsche weg.
funktionieren denn die beispiele nicht? was für probleme haben die beispiele?

DeddyH 2. Jul 2020 12:18

AW: Ordner nicht leer
 
Wieso ist das der falsche Weg? Exakt auf faDirectory zu prüfen wäre definitiv falsch, da auch andere Attribute enthalten sein können. Zur Erklärung: https://www.delphipraxis.net/95180-e...bitmasken.html

kagi3624 2. Jul 2020 12:20

AW: Ordner nicht leer
 
Zitat:

Zitat von KodeZwerg (Beitrag 1468721)
einfach auf 0 prüfen ist der falsche weg.
funktionieren denn die beispiele nicht? was für probleme haben die beispiele?

Ja doch. Das funktioniert wunderbar. Ich habe nur Probleme mit der Delphi Syntax bzw damit, dass etwas stimmt wenn es grade auf null gesetzt wurde.

DeddyH 2. Jul 2020 12:22

AW: Ordner nicht leer
 
In dem Moment, wo ein Unterverzeichnis z.B. das Archiv-Attribut gesetzt hat, funktioniert die exakte Prüfung nicht mehr, d.h. das Verzeichnis wird als Datei erkannt.

KodeZwerg 2. Jul 2020 12:27

AW: Ordner nicht leer
 
hehe, warste schneller als ich :-) das wollte ich damit, ohne ausführlich zu werden, sagen.


//edit
vielleicht hilft dir das hier kagi3624 -> Vergleichsoperatoren
hat jetzt nicht direkt was mit bitmasken zu tun aber da las ich auch vorhin ne frage die der link vielleicht ausführlicher beantwortet, um hinter der logik von delphi ein wenig durchzuschauen.

Andreas13 2. Jul 2020 12:34

AW: Ordner nicht leer
 
Hallo Kagi3624,
darf ich Dir zwei exzellente Fachbücher zu Deinem Delphi 6 empfehlen?

Walter Doberenz und Thomas Kowalski:
1):
Borland Delphi 6. Grundlagen und Profiwissen
https://www.amazon.de/Borland-Delphi.../dp/3446217347
2):
Borland Delphi 6 Kochbuch
https://www.amazon.de/Borland-Delphi.../dp/3446217355

Dort findest Du eine sehr gute Einführung in Delphi 6, u. a. auch in das Thema "Bitweise Operationen": --> Band 2: "Einen Wert auf Bit-Ebene manipulieren"
Gruß, Andreas

kagi3624 2. Jul 2020 13:06

AW: Ordner nicht leer
 
Ok, um zu testen, ob ich es verstanden habe, habe ich die Suchfunktion abgewandelt um alle Dateinamen ohne die Unterordner in ein Memofeld zu schreibeiben.

Code:
function TForm1.DirContainsFiles(const Dirname: string): Boolean;
var
  Rec: TSearchRec;
  SearchPattern: string;
begin
  Memo3.Text := '';
  Result := false;
  SearchPattern := IncludeTrailingPathDelimiter(Dirname) + '*.*';
  if FindFirst(SearchPattern, faAnyFile, Rec) = 0 then
    try
      repeat
        if Rec.Attr and faDirectory = 0 then begin
          Result := true;
          Memo3.Lines.Add(Rec.Name);
        end;
      until (FindNext(Rec) <> 0);
    finally
      SysUtils.FindClose(Rec);
    end;
end;
Es funktioniert auch. Ich frage mich bloß, wieso man in diesem Fall nicht nach den '.' und '..' suchen muss.

DeddyH 2. Jul 2020 13:13

AW: Ordner nicht leer
 
Weil '.' für das aktuelle und '..' für das übergeordnete Verzeichnis steht, es sind also Verzeichnisse. Daher ist das Flag gesetzt und der Vergleich ergibt nicht 0, sondern faDirectory. Hast Du mein Tutorial schon gelesen, das ich weiter oben verlinkt hatte?

himitsu 2. Jul 2020 17:09

AW: Ordner nicht leer
 
Jemand könnte für die Attribute mal auf die blöde Idee kommen das in ein SET zu ändern, dann kann man schön ein IN benutzen.

Gut, dann kompilieren viele Codes nicht mehr,
aber man kann sich auch gern einen ClassOperator für diesen Vergleich erstellen, damit man bei diesem Integer auch das IN benutzen kann.

Delphi-Quellcode:
if faDirectory in Rec.Attr then begin
:angle:


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz