Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Verzechniss: alle beinhaltenden Ordner ermitteln? (https://www.delphipraxis.net/119938-verzechniss-alle-beinhaltenden-ordner-ermitteln.html)

LuCSteR 3. Sep 2008 12:57


Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Hi,

gibt es eine Funktion oder Eigenschaft, die mir von einem bestimmten Pfad die Namen alle darin befindlichen Ordner zurückgibt?

Grüße

mkinzler 3. Sep 2008 12:59

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Nein, aber Ordner sind besondere Dateien. Du kannst sie wie Datein finden (.FindFirst/.FindNext)

HenKst 3. Sep 2008 13:01

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Schau dir mal FindFirst, FindNext, FindClose an.

Damit findest du jeweils eine Datei bzw einen Ordner im angegebenen Pfad.
Ich Kenne keine Funktion die mehrere auf einmal zurückgiebt.

Yey 10 Posts^^

DeddyH 3. Sep 2008 13:04

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Du könntest Dir TStrings als Parameter an die Prozedur übergeben. Diese werden dann von der Prozedur befüllt.

LuCSteR 3. Sep 2008 13:09

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Zitat:

Es wird dringend davon abgeraten diese Lösung zu benutzen, da so die interne Reihenfolge durcheinander gebracht werden kann. So ist nicht garantiert, dass FindNext die richtigen Dateien für das Löschen findet.
(In meinem Fall kopieren)

Deshalb wollte ich auf diesen Weg verzichten.
Bei der FTP Komponente "synapse" gibt es auch eine Funktion, die mir alle Datei/Ordner-Namen in eine Liste speichert. Wenn es eine solche Funktion bei dieser speziellen Komponente gibt, warum gibt es denn keine in den Standardbibliotheken? Mhh...

@ DaddyH:
Von welcher Prozedur sprichst du?
Wie oben erwähnt, macht es nat. Sinn die Namen in einer Liste zu speichern.

DeddyH 3. Sep 2008 13:13

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Von Löschen hattest Du nichts gesagt. Und die angesprochene Prozedur könnte z.B. die folgende Signatur haben:
Delphi-Quellcode:
procedure ListSubDirs(Dirname: string;const sList: TStrings);

HenKst 3. Sep 2008 13:16

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Synapse hat diese Liste weil es eben einen FTPbefehl gibt der die liste zurückgibt.
Da macht aber der Server auch nichts anderes als das system äquivalent zu FindFirst, FindNext...

Ich weiss jetzt nicht woher dein Quote war aber das scheint mir so als wäre das eine schleife die eine Datei löscht sobald sie gefunden ist.
Wenn du dir eine Liste mit einer Find schleife erstellst und nach der Schleife eben die Dateien/Ordner aus der Liste löschst, sollte keine interne Reihenfolge darunter leiden.

LuCSteR 3. Sep 2008 13:23

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Hab auch nichts von löschen gesagt, sondern
Zitat:

(In meinem Fall kopieren)
:))

Komm ich quasi um die FindNext Sache nich drumherum oder?

Das Zitat stamm von
Delphi-Treff.

DeddyH 3. Sep 2008 13:29

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Was ist an FindFirst/FindNext so schlimm?

LuCSteR 3. Sep 2008 13:41

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
FindFirst und FindNext geben mir nur Longint zurück, nicht den Namen(string) des gefundenen Elements.

Delphi-Quellcode:
ChangeCurrentDir(TempDownloadDir);
sList[0]:=FindFirst(GetCurrentDir);
sList[i]:=FindNext(GetCurrentDir);
...

mkinzler 3. Sep 2008 13:43

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Es übergibst doch eine TSerachRec-Struktur, in der steht doch alles

DeddyH 3. Sep 2008 13:43

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Richtig, und was steht im TSearchRec?

LuCSteR 3. Sep 2008 13:57

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Delphi-Quellcode:
//Ordnernamen in einem Verzeichnis ermitteln
procedure ListSubDirs(Dir: string; var sList: TStrings);
begin
  Dir:=TempDownloadDir
  ChangeCurrentDir(Dir);
  FindFirst(GetCurrentDir, faDirectory, sList);
  FindNext(sList);
end;
So siehts bis jetzt aus. In dem Fall findet er nur den ersten Ordner und den folgenden. So möchte ich es aber haben:
Delphi-Quellcode:
//Ordnernamen in einem Verzeichnis ermitteln
procedure ListSubDirs(Dir: string; var sList: TStrings);
begin
  Dir:=TempDownloadDir
  ChangeCurrentDir(Dir);
  FindFirst(GetCurrentDir, faDirectory, sList);
  while {letzter Ordner nicht gefunden} do FindNext(sList);
end;
Wie könnte ich den letzten Ordner ermitteln? Halt diese Schleife zum Ende zwingen?
Und ich verstehe immer noch nicht was ich mit den Longint-Werten anstellen soll? Was sagen die aus?

DeddyH 3. Sep 2008 13:59

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Sry, aber bevor Du hier weiterfragst, solltest Du mal einen Blick in die Hilfe werfen, gewisse Grundlagen darf man schon voraussetzen. Und danach wirst Du über die DP-Suche zu FindFirst/FindNext einige Beispiele finden.

Aurelius 3. Sep 2008 14:01

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Schau dir mal diesen Beitrag aus der Codelib an, ist eigentlich alles verständlich erklärt: http://www.delphipraxis.net/internal...ight=findfirst

LuCSteR 3. Sep 2008 14:04

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Ein Blick in die Hilfe würde ich ja befürworten, wenn ich mit Delphi arbeiten könnte. Bei Lazarus gibt es keine lokale Hilfe. Und die Online-Hilfe ist leider nur eine kleine "Wiki"...

Grundlagen in Bezug auf was?

DeddyH 3. Sep 2008 14:10

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Dann solltest Du aber kenntlich machen, dass Du mit Lazarus arbeitest. Ansonsten schau mal in der DP nach z.B. Hier im Forum suchenFindAllFiles

LuCSteR 3. Sep 2008 14:36

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Naja habs ja im ersten Post angegeben: Sprache=Lazarus...

Also nun siehts so aus.
Delphi-Quellcode:
//Ordnernamen in einem Verzeichnis ermitteln
procedure ListSubDirs(Dir: string; var sList: TStrings);
var
  SR: TSearchRec;
 
begin
  Dir:=TempDownloadDir;
  if FindFirst(Dir, faDirectory, SR)=0 then
    sList.Add(SR.Name);
    try
      while FindNext(SR)<>0 do
        begin
          FindNext(SR);
          sList.Add(SR.Name);
        end;
    finally
      FindClose(SR);
    end;
end;
Denke das sollte so funktionieren. Der Compiler meckert aber beim finally:
Unit1.pas(287,19) Error: Incompatible type for arg no. 1: Got "TSearchRec", expected "LongWord"

Da steht aber: FindClose(Var F:TSearchRec);
Verstehe ich nicht ganz :s

---

Ich seh gerade das es FindClose 2 mal gibt. Ich seh aber nicht aus welcher Bibliothek mein FindClose ist. Weis das jmd.?

DeddyH 3. Sep 2008 14:43

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
SysUtils.FindClose

LuCSteR 3. Sep 2008 15:18

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Beim kompilieren gibts keine Fehler aber bei der Nutzung :s

In der While-Schleife gibts nen Fehler bei: sList.Add(SR.Name);

DeddyH 3. Sep 2008 15:28

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Was übergibst Du denn als sList an die Prozedur? Und wieso als Var-Parameter?

LuCSteR 3. Sep 2008 15:34

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Ich übergebe ihr ein nicht initialisiertes s:TSrings. Also "leer".
Stimmt, sList als var zu deklarieren war sinnlos. Aber daran haperts nicht.
Delphi-Quellcode:
ListSubDirs(TempDownloadDir, s);
Stimmt die Benutzung mit s nicht? Habe mit TStrings vorher noch nix gemacht. Allerdings scheint es keine Syntax Fehler zu geben...

DeddyH 3. Sep 2008 15:48

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Du kannst entweder z.B. ComboBox.Items übergeben oder Dir eine Stringlist erstellen.
Delphi-Quellcode:
var sl: TStringlist;
begin
  sl := TStringlist.Create;
  try
    ListSubDirs(TempDownloadDir,sl);
    ...
  finally
    sl.Free;
  end;
end;

LuCSteR 3. Sep 2008 16:31

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Irgendwie traurig, ich schlag mich den ganzen Nachmittag mit so einem trivialen Problem rum. Warum gibt es nicht einfach eine Standard Funktion, womit man ein Verzeichnis in ein anderes verschieben kann?

Das ist echt zum Mäuse melken.

Aufruf:
Delphi-Quellcode:
var
  i:integer;
  s:TStringList;
  h1, h2:string;

begin //alles in TempDownloadDir nach DownloadDir kopieren, danach TempDownloadDir löschen
      s:=TStringList.Create;
      ListSubDirs(TempDownloadDir, s);

      h1:=TempDownloadDir;
      //letzten Backslash abschneiden
      Delete(h1, Length(h1), 1);
     
      h2:=DownloadDir;
      //letzten Backslash abschneiden
      Delete(h2, Length(h2), 1);
     
      try
        for i:=0 to s.Count-1 do MoveDir(h1+s[i], h2+s[i]);
      finally
        s.Free;
      end;
     
      DeleteFile(h1);
end;
Das MoveDir funktioniert (getestet) zb. so MoveDir(h1, h2); einwandfrei...Nur nicht in der Schleife mit der StringListe...
Ich mache da morgen weiter und werd mal schaun, was überhaupt in der Liste drinne steht. Kein Bock jetzt mehr.

Danke für die Hilfe DaddyH.

DeddyH 3. Sep 2008 16:33

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Hättest Du mal früher gesagt, was Du machen möchtest, hätte ich noch Hier im Forum suchenSHFileOperation als Alternative angeboten.

LuCSteR 3. Sep 2008 16:52

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Die Suche habe ich auch schon kräftig durchforstet.
Ich erklär vll mal kurz mein Anliegen:

es gibt nen Download und nen TempDownload Ordner. TempDownload wird beim Programmstart erstellt und beim schließen wieder gelöscht. Das klappt. Jetzt will ich, das alle Ordner die sich in TempDownload befinden nach Download befördert werden (wenn dafür die Option vom Nutzer getroffen wurde). Das MoveDir funktioniert ja einwandfrei. Nur muss ich ja möglicherweise nicht nur einen Ordner im tempDownload verschieben, sondern auch mehrere, deswegen muss ich MoveDir nicht auf TempDownload, sondern auf die einzelnen Ordner anwenden. Dafür brauch ich wiederum deren Namen.
Und da ist mein Problem. Die Funktion für die Ordnernamenbestimmung funktioniert nicht. Kommen zwar keine Fehler aber es wird auch garnichts in die String-Liste geschrieben...Hab das jetzt mal getestet.

Naja und für meinen Fall gibts noch nix im Forum :)

Wie gesagt, bis morgen.

Trotzdem könnte vll nochmal jmd schaun, ob meine StringList-Item-Ansteuerung so richtig ist und funktioniert das überhaupt, das wenn die ListSubDirs einen TStrings erwartet aber eine TStringList bekommt? Wie gesagt kenn mich da leider garnicht aus.

Grüße

DeddyH 3. Sep 2008 17:12

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
TStringlist ist ein Nachkomme von TStrings, somit automatisch auch vom Typ TStrings.

LuCSteR 4. Sep 2008 08:54

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Es werden keine Elemente in die StringListe gepackt. Der Count ist 0.

DeddyH 4. Sep 2008 09:03

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Delphi-Quellcode:
procedure ListSubDirs(sDir: string; const sList: TStrings);
var Rec: TSearchRec;
begin
  sList.BeginUpdate;
  try
    sList.Clear;
    if FindFirst(IncludeTrailingPathDelimiter(sDir) + '*.*', faDirectory or faReadOnly or faHidden or faArchive, Rec) = 0 then
    begin
      repeat
        if ((Rec.Attr and faDirectory) = faDirectory) and (Rec.Name <> '.') and (Rec.Name <> '..') then
          sList.Add(Rec.Name);
      until FindNext(Rec) <> 0;
      SysUtils.FindClose(Rec);
    end;
  finally
    sList.EndUpdate;
  end;
end;
Ohne Gewähr, da aus dem Kopf getippt.

LuCSteR 4. Sep 2008 09:20

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Okay, die Prozedur funktioniert. 1a!
Ich glaube mit der Delphi Hilfe wäre ich auch von alleine auf die ganzen fehlenden Bedingungen gekommen :S.
Aber so.
Naja vielen Dank. Jetzt komm ich endlich mit meinem wirklichen Problem weiter :)

LuCSteR 13. Jan 2009 09:53

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
hi,

wie wäre denn die Funktion umzuschreiben, wenn man anstatt Ordnern die Dateinamen ermitteln will? (Beitrag #29)


grüße

nahpets 13. Jan 2009 10:16

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Hallo,

statt faDirectory faAnyFile nehmen.

Kurz aus der Delphi 7-Hilfe kopiert:

Code:
FindFirst (Funktion)

Siehe auch   Delphi-Beispiel   C++ Beispiel

Die Funktion sucht in einem Verzeichnis nach dem ersten Vorkommen einer bestimmten Datei mit den angegebenen Attributen.

Unit

SysUtils

Kategorie

Dateiverwaltung

Delphi-Syntax:

function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;

C++ Syntax:

extern PACKAGE int __fastcall FindFirst(const AnsiString Path, int Attr, TSearchRec &F);

Beschreibung

FindFirst sucht im Verzeichnis Path nach dem ersten Eintrag, der mit dem angegebenen Dateinamen und den festgelegten Attributen übereinstimmt. Das Ergebnis wird im Parameter F zurückgegeben. Den Feldern dieses Datensatzes können Sie die benötigten Informationen entnehmen. FindFirst gibt im Erfolgsfall 0 zurück, ansonsten einen Fehlercode.

Der Konstantenparameter Path enthält das Verzeichnis und die Dateinamensmaske. Es können auch Platzhalterzeichen verwendet werden. '.\test\*.*' gibt beispielsweise alle Dateien im aktuellen Laufwerk an.

Der Parameter Attr gibt an, welche speziellen Dateien zusätzlich zu den normalen Dateien angezeigt werden. Die folgenden Konstanten können verwendet werden:

Konstante   Beschreibung
faReadOnly   Schreibgeschützte Datei
faHidden   Verborgene Datei
faSysFile   Systemdatei
faVolumeID   Laufwerks-ID
faDirectory   Verzeichnis
faArchive   Archivdatei
faAnyFile   Beliebige Datei
Sie können auch mehrere Attribute kombinieren, indem Sie die betreffenden Konstanten hinzufügen (Delphi) bzw. eine ODER-Verknüpfung (C++) durchführen. Soll beispielsweise zusätzlich zu den normalen auch nach schreibgeschützten und versteckten Dateien gesucht werden, übergeben Sie als Parameter Attr in Delphi den Wert (faReadOnly + faHidden) bzw. in C++ den Wert (faReadOnly | faHidden).

Hinweis:   FindFirst weist Ressourcen (Speicher) zu, die durch einen Aufruf von FindClose wieder freigegeben werden müssen.
:   Manche Dateiattributkonstanten sind nicht auf allen Plattformen gültig. So können beispielsweise faVolumeID und faArchive nicht in Linux verwendet werden.
und das Beispiel dazu:
Code:
In diesem Beispiel befinden sich ein Eingabefeld, eine Schaltfläche, ein String-Gitter und sieben Kontrollkästchen in einem Formular. Die Kontrollkästchen entsprechen den sieben möglichen Dateiattributen. Beim Klicken auf die Schaltfläche wird der in das Eingabefeld eingegebene Pfad nach Dateien mit den angegebenen Attributen durchsucht. Name und Größe der übereinstimmenden Dateien werden dann in das String-Gitter eingefügt.

procedure TForm1.Button1Click(Sender: TObject);

var
  sr: TSearchRec;
  FileAttrs: Integer;
begin
  StringGrid1.RowCount := 1;
  if CheckBox1.Checked then
    FileAttrs := faReadOnly
  else
    FileAttrs := 0;
  if CheckBox2.Checked then
    FileAttrs := FileAttrs + faHidden;
  if CheckBox3.Checked then
    FileAttrs := FileAttrs + faSysFile;
  if CheckBox4.Checked then
    FileAttrs := FileAttrs + faVolumeID;
  if CheckBox5.Checked then

    FileAttrs := FileAttrs + faDirectory;
  if CheckBox6.Checked then
    FileAttrs := FileAttrs + faArchive;
  if CheckBox7.Checked then

    FileAttrs := FileAttrs + faAnyFile;

  with StringGrid1 do
  begin
    RowCount := 0;

    if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then

    begin
      repeat
        if (sr.Attr and FileAttrs) = sr.Attr then
        begin
        RowCount := RowCount + 1;
        Cells[1,RowCount-1] := sr.Name;
        Cells[2,RowCount-1] := IntToStr(sr.Size);
        end;
      until FindNext(sr) <> 0;
      FindClose(sr);
    end;
  end;
end;

LuCSteR 13. Jan 2009 10:47

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Habs getestet. Wird nix in die Stringliste geschrieben :(

Delphi-Quellcode:
//Listet alle Namen von Dateien in einem Verzeichnis
procedure ListDirFiles(sDir: string; const sList: TStrings);
var Rec: TSearchRec;
begin
  sList.BeginUpdate;
  try
    sList.Clear;
    if FindFirst(IncludeTrailingPathDelimiter(sDir) + '*.*', faAnyFile or faReadOnly or faHidden or faArchive, Rec) = 0 then
    begin
      repeat
        if (((Rec.Attr and faAnyFile) = faAnyFile) and (Rec.Name <> '.') and (Rec.Name <> '..')) then sList.Add(Rec.Name);
      until FindNext(Rec) <> 0;
      SysUtils.FindClose(Rec);
    end;
  finally
    sList.EndUpdate;
  end;
end;
Habe auch probiert:
Delphi-Quellcode:
...
if FindFirst(IncludeTrailingPathDelimiter(sDir), faAnyFile, Rec) = 0 then
...
und
Delphi-Quellcode:
...
if (((Rec.Attr and faAnyFile) = Rec.Attr) and (Rec.Name <> '.') and (Rec.Name <> '..')) then sList.Add(Rec.Name);
...
Irgendwo ist noch nen kleiner Fehler drinne.

DeddyH 13. Jan 2009 11:03

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Versuch es mal mit
Delphi-Quellcode:
if (((Rec.Attr and faDirectory) = 0) then

nahpets 13. Jan 2009 11:14

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Hallo,

schau mal bitte hier: http://www.delphipraxis.net/internal...ight=faanyfile, da hatte vor wenigen Tagen schonmal jemand ein derartiges Problem, eventuell ist für Dich ein passender Lösungsansatz dabei.

Ansonsten schau bitte mal in der Suche, es gibt da einige Threads zu dem Thema, eventuell wurde an anderer Stelle die Problematik schon mal unter Lazarus erörtert. Auf die Schnelle fällt mir da jetzt keine Lösung ein.
Achso: faAnyFile enthält (soweit ich weiß) bereits faReadOnly, faHidden und faArchive, liegts daran?

DeddyH 13. Jan 2009 11:18

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
Zitat:

Zitat von nahpets
faAnyFile enthält (soweit ich weiß) bereits faReadOnly, faHidden und faArchive, liegts daran?

Solange die Attribute verodert und nicht addiert werden, kann nichts passieren.

LuCSteR 13. Jan 2009 11:35

Re: Verzechniss: alle beinhaltenden Ordner ermitteln?
 
DeddyH hats mal wieder gelöst :) Vielen Dank


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:24 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