Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Prüfen ob ein verzeichnis die gewünschte erweiterungen hat ? (https://www.delphipraxis.net/79049-pruefen-ob-ein-verzeichnis-die-gewuenschte-erweiterungen-hat.html)

mimi 15. Okt 2006 13:53


Prüfen ob ein verzeichnis die gewünschte erweiterungen hat ?
 
Hallo,
in einem aktuellen Projekt muss ich prüfen ob es in den verzeichnisen bestimmte erweiterungen gibt oder nicht....

ich habe es zurerst so versucht
Delphi-Quellcode:
function GetAnderItem(dir:String;extList:String):Boolean;
var
  sr:TSearchRec;
  ok:Boolean;
begin
  OK := False;
  if FindFirst(Dir+'*.*', $23,SR) = 0 then begin
    repeat
      // Der Eintrag darv kein . oder .. sein und muss in der liste stehen dann ok auf True
      if (sr.Name[1] <> '.') and (pos(UpperCase(ExtractFileExt(sr.name)),extlist) > 0) then begin
        ok:=True;
        result:=ok;
      end;
    until ok or (FindNext(sr) <> 0);
  end;
       GetPreviousDirectory
  if (FindFirst(Dir+'*', faDirectory,SR) = 0) then begin
    repeat
     if (sr.Name[1] <> '.') and ((sr.Attr and faDirectory) = faDirectory) then
     GetAnderItem(dir+sr.name+'\',extlist);
    until FindNext(sr) <> 0;
    FindClose(sr);
  end;
  result:=ok;
// dieser code gibt auch immer nur false zurück
dann habe ich im internet einen code gefunden und ihn angepasst:
Delphi-Quellcode:
function GetFilesInDirectory(ADirectory: string; AMask: String; ARekursiv: Boolean;ok:Boolean = False):Boolean;
var
  SR: TSearchRec;
begin
  ok:=ok;
  if (ADirectory<>'') and (ADirectory[length(ADirectory)]<>'\') then ADirectory:=ADirectory+'\';
  if (FindFirst(ADirectory,faAnyFile-faDirectory,SR)=0) then begin
    repeat
      if (SR.Name[1]<>'.') and ((sr.Attr and faAnyFile) = faAnyFile) and (pos(UpperCase(ExtractFileExt(sr.name)),AMask) > 0)then
        ok:=true;
    until (ok ) or (FindNext(SR)<>0);
    FindClose(SR);
  end;

  if ARekursiv then
    if (FindFirst(ADirectory+'*.*',faDirectory,SR)=0) then
    begin
      repeat
        if SR.Name[1]<>'.' then
          GetFilesInDirectory(ADirectory+SR.Name,AMask,True,ok);
      until FindNext(SR)<>0;
      FindClose(SR);
    end;
  result:=ok;
end;
allerding gibt er immer nur false zurück

ich hoffe ihr könnte mir wie meistens weiter helfen.

Vielen dank im vorraus !

Christian Seehase 15. Okt 2006 14:07

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
Moin Michael,

erster Fehler:

Delphi-Quellcode:
if (sr.Name[1] <> '.')
es muss heissen:

Delphi-Quellcode:
if (sr.Name <> '.') and (sr.Name <> '..')
da es das Dateisystem durchaus erlaubt, dass ein Verzeichnis oder eine Datei mit . anfangen.
(in der Konsole, oder aus einem Programm heraus lässt sich das erzeugen, im Explorer nicht.)

Dann:
Delphi-Quellcode:
((sr.Attr and faAnyFile) = faAnyFile)
Wird niemals true, da faAnyFile eine Kombination aller möglicher Flags ist, ein Verzeichnis/eine Datei, aber niemals alle Flags enthalten können. (z.b.: Eine Datei kann nicht das Flag faDirectory haben, ein Verzeichnis nicht faReadOnly).

Hier
Delphi-Quellcode:
(pos(UpperCase(ExtractFileExt(sr.name)),AMask)
stellt sich mir die Frage, wie AMask aussieht. ExtractFileExt gibt .ext zurück (also mit .)

Hier
Delphi-Quellcode:
if (FindFirst(ADirectory,faAnyFile-faDirectory,SR)=0) then begin
bringt das faAnyFile-faDirectory nichts, da FindFirst nicht nach Attributen filtert.
[EDIT]
Ausserdem sollte man bei Bitfeldern wie dem Attribut keinesfalles + und - benutzen, sondern OR (statt +) bzw. AND NOT statt -
[/EDIT]

mimi 15. Okt 2006 14:15

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
@Christian Seehase
nein das ist so richtig weil sr.name ist ja ein string und strings fangen von eins an zu zählen
also ist sr.name[1] das erste zeichen und sobalt da ein .. oder . wird es ausgelassen.


Amask ist so aufgebaut .ext.ext.ext.

ich habe es jetzt so geändert alledings kommt immer noch ein fehler: verzeichnise die keine der gewünschten dateien enthalten werden trozdem mitbeachtet:
Delphi-Quellcode:
function GetFilesInDirectory(ADirectory: string; AMask: String; ARekursiv: Boolean; var ok:Boolean ):Boolean;
var
  SR: TSearchRec;
  ok1:Boolean;
begin
  ok1:=ok;
  if (ADirectory<>'') and (ADirectory[length(ADirectory)]<>'\') then ADirectory:=ADirectory+'\';
  if (FindFirst(ADirectory,faAnyFile ,SR)=0) then begin
    repeat
      if (SR.Name[1]<>'.') and ((sr.Attr or faAnyFile) = faAnyFile) and (pos(UpperCase(ExtractFileExt(sr.name)),AMask) > 0)then
        ok1:=true;
    until (ok1 ) or (FindNext(SR)<>0);
    FindClose(SR);
  end;

  if ARekursiv then
    if (FindFirst(ADirectory+'*.',faDirectory,SR)=0) then
    begin
      repeat
        if (SR.Name[1]<>'.') and (sr.attr and faDirectory > faDirectory) then begin
          ok1:=False;
          GetFilesInDirectory(ADirectory+SR.Name,AMask,True,ok1);
        end;
      until FindNext(SR)<>0;
      FindClose(SR);
    end;
  result:=ok1;
end;

ErazerZ 15. Okt 2006 15:05

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
also hier ist eine funktion die einfach einen ordner nach erweiterungen durchsucht, findet der eine erweiterung bricht er ab, natürlich kannst noch einwenig umändern zb. um die gefundenen dateien in einer stringlist zu speichern

Delphi-Quellcode:
// uses Windows;
function IstErweiterungImOrdner(Pfad, Erweiterung: String): Boolean;
var
  lpFindFileData: TWIN32FindData;
  hFindFile: THandle;
begin
  Result := False;
  if (Erweiterung = '') or (Pfad = '') then Exit;
  if (Erweiterung[1] <> '.') then Erweiterung := '.' + Erweiterung;
  Pfad := IncludeTrailingBackslash(Pfad);
  Pfad := Pfad + '*.*';
  ZeroMemory(@lpFindFileData, sizeof(TWIN32FindData));
  hFindFile := FindFirstFile(PChar(PFad), lpFindFileData);
  if (hFindFile <> 0) and (hFindFile <> INVALID_HANDLE_VALUE) then
  begin
    repeat
      with lpFindFileData do
      begin
        if (dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0) then
        begin
          if (String(cFilename) <> '.') and (String(cFilename) <> '..') then
          begin
            if UpperCase(Erweiterung) = UpperCase(ExtractFileExt(String(cFilename))) then
            begin
              Result := True;
              break;
            end;
          end;
        end;
      end;
    until not Windows.FindNextFile(hFindFile, lpFindFileData);
    Windows.FindClose(hFindFile);
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  if IstErweiterungImOrdner('c:\', '.exe') then
    ShowMessage('exe dateien sind im ordner c:\ vorhanden!');
end;

marabu 15. Okt 2006 15:22

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
Hallo,

ich habe meinen Code von neulich etwas anpasst, damit er auch mehrere Erweiterungen prüfen kann:

Delphi-Quellcode:
// uses FileCtrl;
function FileCount(const dir, masks: String): Integer;
begin
  with TFileListBox.CreateParented(HWND(-3)) do
  try
    Mask := masks;
    Directory := IncludeTrailingPathDelimiter(dir);
    FileType := [ftArchive];
    Result := Items.Count;
  finally
    Free;
  end;
end;


begin
  if FileCount('C:\Media\Audio\', '*.MP3;*.WAV') = 0 then
    ShowMessage('nix gefunden');
end;
Mit nur wenigen Zeilen mehr lässt sich auch eine rekursive Untersuchung eines Verzeichnisbaumes bewerkstelligen.

Grüße vom marabu

mimi 15. Okt 2006 15:55

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
@ErazerZ
dein code geht leider nicht in unterverzeichnise rein

@marabu
dein codem bring leider das gleiche ergbnis wie mein code:
also hier mal bischen mehr code:
Delphi-Quellcode:
function GetFilesInDirectory(ADirectory: string; AMask: String; ARekursiv: Boolean):Boolean;
var
  SR: TSearchRec;
  ok:Boolean;
begin
  ok:=False;
  if (ADirectory<>'') and (ADirectory[length(ADirectory)]<>'\') then ADirectory:=ADirectory+'\';
  if (FindFirst(ADirectory + '*.*',faAnyFile ,SR)=0) then begin
    repeat
      if (SR.Name[1]<>'.') and ((sr.Attr or faAnyFile) = faAnyFile) and (pos(UpperCase(ExtractFileExt(sr.name)),AMask) > 0)then begin
        ok:=True;
        result:=ok;
      end
    until (ok ) or (FindNext(SR)<>0);
    FindClose(SR);
  end;

  if ARekursiv then
    if (FindFirst(ADirectory+'*.*',faDirectory,SR)=0) then begin
      repeat
        if (sr.name[1] <> '.') and (sr.Attr and faDirectory >0) then begin
          GetFilesInDirectory(ADirectory+sr.name,AMask,ARekursiv);
        end;
      until (FindNext(SR)<>0);
      FindClose(SR);
    end;
 result:=ok;
end;
procedure TPlaylisten.LoadDir(dir:String; var t:Boolean);
var
  search: TSearchRec;
  directory: string;
  sl:TStringList;
  count:Integer;
begin
  directory := ExtractFilePath(dir);
  t:=GetAnderDir(dir,stdext,faAnyFile or faDirectory );
  if FileCount(directory,'*.M4A')>0  then begin
    if Assigned(onPlaylisteAdd) then
    onPlaylisteAdd(directory ,GetPrvDir(directory));
  end;

  // find all files
  // damit auch verzeichnise eingelesen werden die keine unterverzeichnise enhalten
  if (isAnder = False) and (FileCount(directory,'*.M4A')>0) then begin
    if Assigned(onPlaylisteAdd) then
    onPlaylisteAdd(directory ,GetPrvDir(directory));
  end;

  if FindFirst(directory + '*.*', $23, search) = 0 then begin
    repeat
      if pos(uppercase(ExtractFileExt(search.name)),stdext) > 0 then begin
        if Assigned(onAddItem) then
          onAddItem(directory + search.Name,search.Name);
      end;
    until FindNext(search) <> 0;
  end;

  // Subdirectories/ Unterverzeichnisse
  if FindFirst(directory + '*.', faDirectory, search) = 0 then begin
    repeat
      if ((search.Attr and faDirectory) = faDirectory) and (search.Name[1] <> '.') then begin
        isAnder:=True;
        if t = False then
        if (Assigned(onPlaylisteAdd)) and ((FileCount(directory,'*.M4A')>0)) then onPlaylisteAdd(directory + search.Name,search.Name);
        LoadDir(directory + search.Name + '\',t);
        isAnder:=False;
      end;
    until FindNext(search) <> 0;
    FindClose(search);
  end;
  //if t = false then
  if Assigned(onplaylistnewadd) then onplaylistnewadd(GetAnderDir(directory + search.Name + '\',stdext,faDirectory));
end; // LoadDir
so loaddir soll jetzt verschiedne verzeichnise komplet einlesen und dabei sortieren das einlesen habe ich hinbekommen nur das mit der Filterfunktion leider nicht.
ich erzeuge daraus eine baumstruktur darum die drei ereignise ich denke sie sollte selbsterkläerend sein.
ich hatte folgende gedanken:

programm sucht im angeben verzeichnise nach unterverzeichnisen mit den entsprechenden endungen.
findet es was soll der root knoten das suchverzeichnis dastellen z.b.
ich suche jetzt in c:\music soll der rooknoten music heißen
soablt er was findet soll er es den root knoten hinzufügen
dann das nächte verzeichnis: sind dort die gesuchten dateien drin hinzufügen zum baum allerding soll das hauptverzeichnis von den dateien ebenfall im zum root dazugeben werden z.b.
c:\Music\1\1.m4a

jetzt suche ich nach m4a soll der baum so aussehen:
Music
1
1.m4A

ich hoffe ihr versteht wie ich meine. ich schaffe es einfach nicht.

GuenterS 15. Okt 2006 16:08

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
Zitat:

Zitat von mimi
@Christian Seehase
nein das ist so richtig weil sr.name ist ja ein string und strings fangen von eins an zu zählen
also ist sr.name[1] das erste zeichen und sobalt da ein .. oder . wird es ausgelassen.

Eben, da werden dann auch Verzeichnisse ausgelassen wie ".Test", ".Nochwas', usw.

Christian Seehase 15. Okt 2006 16:08

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
Moin Michael,

Zitat:

Zitat von mimi
also ist sr.name[1] das erste zeichen und sobalt da ein .. oder . wird es ausgelassen.

Stimmt, aber genau das ist falsch, denn ein Verzeichnis darf durchaus mit einem Punkt beginnen (eine Datei auch).
Heisst ein Verzeichnis,z.B., ".temp", so wird es bei der Abfrage auf sr.name[1] auch ausgelassen, es sollen ja aber wohl nur die Verzeichnisse . und .. ausgelassen werden.


Diese Zeile

Delphi-Quellcode:
if (SR.Name[1]<>'.') and ((sr.Attr or faAnyFile) = faAnyFile) and (pos(UpperCase(ExtractFileExt(sr.name)),AMask) > 0)then
Müsste so aussehen:
Delphi-Quellcode:
if (SR.Name <> '.') and (SR.Name <> '..') and ((sr.Attr AND faDirectory) = 0) and (pos(LowerCase(ExtractFileExt(sr.name)),AMask) > 0)then
Erklärung:
Delphi-Quellcode:
(SR.Name <> '.') and (SR.Name <> '..')
siehe oben.

Delphi-Quellcode:
((sr.Attr AND faDirectory) = 0)
Ist das Bit, dass ein Directory anzeigt gesetzt, so ist das Ergebnis der AND-Verknüpfung mit der Maske faDirectory = faDirectory bzw. <> 0. Ist das Bit nicht gesetzt (=> Kein Verzeichnis), so ist das Ergebnis = 0.
Wieso hier faAnyFile nicht in Frage kommt, habe ich ja schon weiter oben erklärte (zumindest habe ich es versucht ;-))

Delphi-Quellcode:
(pos(LowerCase(ExtractFileExt(sr.name)),AMask) > 0)
Gemäss Deiner Vorgabe entählt AMask eine Reihe von Erweiterungen in der Form .ext.ext.ext für mein Verständnis also in Kleinschreibung. Deshalb UpperCase durch LowerCase ersetzt. Um ganz sicher zu gehen, kannst Du auch beide Bestandteile von Pos auf die gleiche Schreibweise umwandeln. Evtl. sogar mit AnsiUpperCase oder AnsiLowerCase, falls die Erweiterung Umlaute enthält.

mimi 15. Okt 2006 16:19

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
@Christian Seehase
ok ! das habe ich jetzt verstanden. habe mich schon gewunder warum ausermir es keiner so macht :?
Zitat:

((sr.Attr AND faDirectory) = 0)

Ist das Bit, dass ein Directory anzeigt gesetzt, so ist das Ergebnis der AND-Verknüpfung mit der Maske faDirectory = faDirectory bzw. <> 0. Ist das Bit nicht gesetzt (=> Kein Verzeichnis), so ist das Ergebnis = 0.
Wieso hier faAnyFile nicht in Frage kommt, habe ich ja schon weiter oben erklärte (zumindest habe ich es versucht Wink)
das verstehe ich leider noch nicht so genau was meinst du damit ?
(könne mich mit bit verkpüfungen leider nicht so gut aus)

marabu 15. Okt 2006 16:58

Re: Prüfen ob ein verzeichnis die gewünschte erweiterungen h
 
Hallo Michael,

schau dir das mal an:

Delphi-Quellcode:
procedure GetSubdirsContaining(const dir: TFileName; sExt, sDir: TStrings; recurse: Boolean = False);
var
  i: Integer;
  s: TStrings;
  sr: TSearchRec;
  dirName: TFileName;
begin
  s := TStringList.Create;
  dirName := IncludeTrailingPathDelimiter(dir);
  try
    if FindFirst(dirName + '*.*', faDirectory, sr) = 0 then
    begin
      repeat
        if AnsiStartsText(sr.Name, '..') then
          Continue else
        if sr.Attr and faDirectory = faDirectory then
        begin
          s.Add(dirName + sr.Name);
          Continue;
        end else
        if sExt.IndexOf(ExtractFileExt(sr.Name)) < 0 then
          Continue;

        if sDir.IndexOf(dirName) < 0 then
          sDir.Add(dirName);
      until FindNext(sr) <> 0;
      FindClose(sr);
    end;
    for i := 0 to Pred(s.Count) do
      GetSubDirsContaining(s[i], sExt, sDir, True);
  finally
    s.Free;
  end;
end;

procedure TDemoForm.GatherButtonClick(Sender: TObject);
var
  sExt: TStrings;
begin
  sExt := TStringList.Create;
  sExt.CommaText := '.mp3,.wav,.m4a';
  try
    with DirBox do
    begin
      Items.BeginUpdate;
      Items.Clear;
      GetSubDirsContaining('c:\Media\', sExt, Items, True);
      Items.EndUpdate;
    end;
  finally
    sExt.Free;
  end;
end;
Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 Uhr.
Seite 1 von 2  1 2      

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