![]() |
Verzeichnis auslesen
Hi
Hab mir heute mal auf die Schnelle ne procedure zum Anzeigen von Dateien in einem bestimmten Verzeichnis gebastelt. Es funktioniert auch, ist aber nicht wirklich entgültig so, da es ja zwecks sortieren nach Ordnern und Dateien 2 fast gleiche Codeblöcke sind, die sich z.B. noch zusammenfassen lassen wollen. Vor 1- 2 Monaten hatte doch wer, im alten DF?, ne Procedure geschrieben, die nen Verzeichnis ausliest. Hat jemand den Code noch. Ich habe hier nichts gefunden, außer 'dateinamen in einen ordner abfragen', aber das wars nicht. Wäre ja auch interessant für die FAQ. Der Codeauszug von mir:
Code:
Gruß
var
datei: TSearchRec; a: integer; begin ... s := s + '\*.*'; ListView1.Items.Clear; If FindFirst(s,fadirectory,datei) = 0 then begin while Findnext(datei) = 0 do begin If datei.Attr and fadirectory > 0 then begin ListView1.Items.Add; a := ListView1.Items.Count -1; ListView1.Items.Item[a].Caption := datei.Name; If datei.name <> '..' then ListView1.Items.Item[a].ImageIndex := 1 else ListView1.Items.Item[a].ImageIndex := 2; ListView1.Items.Item[a].SubItems.Add(InttoStr(datei.size)); ListView1.Items.Item[a].SubItems.Add(DateTimetoStr(FileDateToDateTime(datei.time))); end; end; FindClose(datei); end; If FindFirst(s, fadirectory, datei) = 0 then begin while Findnext(datei) = 0 do begin If datei.Attr and fadirectory = 0 then begin ListView1.Items.Add; a := ListView1.Items.Count -1; ListView1.Items.Item[a].Caption := datei.Name; ListView1.Items.Item[a].ImageIndex := 0; ListView1.Items.Item[a].SubItems.Add(InttoStr(datei.size)); ListView1.Items.Item[a].SubItems.Add(DateTimetoStr(FileDateToDateTime(datei.time))); end; end; FindClose(datei); end; end; by Daniel B; Code-Formatierung |
Also mit deiner Methode lässt du den ersten Dateientrag immer aus, auch wenn dieser meistens '.' ist.
Code:
Die Dateien und Verzeichnisse sind dann aber durcheinander, was man jedoch über CustomSort regeln könnte. Es gibt natürlich auch noch andere Möglichkeiten.
var
sr: TSearchRec; Item: TListItem; begin if FindFirst(s, faAnyFile, sr) = 0 then repeat if (sr.Name <> '.') then Continue; Item := ListView1.Items.Add; Item.Caption := sr.Name; if sr.Attr and faDirectory <> 0 then begin if sr.Name <> '..' then ListView1.Items.Item[a].ImageIndex := 1 else ListView1.Items.Item[a].ImageIndex := 2; end else begin Item.ImageIndex := 0; end; Item.SubItems.Add(InttoStr(sr.Size)); Item.SubItems.Add(DateTimetoStr(FileDateToDateTime(datei.time)); until FindNext(se) <> 0; FindClose(sr); end; |
Moin jbg,
eine kleine Ergänzung: Die beiden Einträge . und .. sind seit den Anfängen von DOS in jedem Verzeichnis enthalten. Der einzelne Punkt kann als das aktuelle Verzeichnis verwendet werden, der doppelte als das vorhergehende (was natürlich in einem Rootverzeichnis nicht wirklich was bringt). Diese beiden Verzeichniseinträge werden beim Anlegen des Verzeichnisses erzeugt, und können eigentlich auch nicht verändert werden. Da FindFirst die Dateien (Verzeichnisse) in der Reihenfolge ihres entstehens findet ist eigentlich kein Fall denkbar, in dem . und .. nicht als erstes gefunden werden. Allerdings würde ich mich auch nicht darauf verlassen. ;-) Auf eines möchte ich noch mal ausdrücklich hinweisen, auch wenn's hier offensichtlich überflüssig ist. Es muss immer exakt nach
Code:
getestet werden und nicht nach
if (srSearch.Name <> '.') and (srSearch.Name <> '..') then
Code:
wie es oft zu sehen ist, da das Dateisystem Datei und Verzeichnisnamen mit führenden Punkten zulässt (auch wenn man es eigentlich nie sieht, und über den Explorer nicht zu erzeugen ist).
// FALSCH
if srSearch.Name[1] <> '.' then Bei dieser Gelegenheit möcht ich noch eine Variante zum Thema Directoryinhalte ermitteln aufzeigen:
Code:
Der zweite Parameter kann eine beliebige StringListe sein, es muss keine Listbox sein.
...
public { Public-Deklarationen } procedure GetDirectoryContent(const p_sRoot : string;const p_slResult : TStrings); end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.GetDirectoryContent(const p_sRoot : string;const p_slResult : TStrings); var lbWork : TListBox; begin // Filectrl einbinden für DirectoryExists if not DirectoryExists(p_sRoot) then begin exit; end; lbWork := TListBox.CreateParented(self.Handle); try SendMessage(lbWork.Handle,LB_DIR,DDL_DIRECTORY,lParam(PChar(p_sRoot+StringOfChar('\',ord(AnsiLastChar(p_sRoot) <> '\'))+'*.*'))); lbWork.Items.Delete(lbWork.Items.IndexOf('[..]')); p_slResult.Clear; p_slResult.AddStrings(lbWork.Items); finally FreeAndNil(lbWork); end; end; procedure TForm1.Button1Click(Sender: TObject); begin GetDirectoryContent('k:\winnt',ListBox1.Items); end; In der Ergebnisliste lassen sich Dateien und Verzeichnisse dadurch unterscheiden, dass Verzeichnisse in eckige Klammern eingeschlossen sind ([NAME]). BTW: Mir fehlt bei euch beiden der Resourcenschutzblock try/finally, um ein FindClose zu garantieren. ;-) |
Ich war zu faul, den hinzuschreiben. Ich weis auch nicht ob mein Code Copy&Paste fähig ist, da ich ihn hier im Forumseditor geschrieben habe.
Code:
var
sr: TSearchRec; Item: TListItem; begin if FindFirst(s, faAnyFile, sr) = 0 then try repeat if (sr.Name <> '.') then Continue; Item := ListView1.Items.Add; Item.Caption := sr.Name; if sr.Attr and faDirectory <> 0 then begin if sr.Name <> '..' then ListView1.Items.Item[a].ImageIndex := 1 else ListView1.Items.Item[a].ImageIndex := 2; end else Item.ImageIndex := 0; Item.SubItems.Add(InttoStr(sr.Size)); Item.SubItems.Add(DateTimetoStr(FileDateToDateTime(datei.time)); until FindNext(se) <> 0; finally FindClose(sr); end; end; |
Zitat:
Wäre auch ein wenig schwierig, vom Root aus eine ebene höher zu gehen. Das ist aber auch die einzige mir bekannte Ausnahme. Grüßle, Sebastian |
@ Christian:
Es sind leider nur die Dosnamen. @ jbg: Leider funktioniert dein Code nicht. Zum Laufen habe ich ihn gebracht aber er gibt nichts aus. Gruß |
Ich habs doch gewusst, dass da noch logische Fehler drin sind.
Es darf nicht
Code:
heißen, sondern muss
if (sr.Name <> '.') then Continue;
^^^^
Code:
heißen
if (sr.Name = '.') then Continue;
^^^ |
Hier jetzt mein aktueller Code:
Code:
Gruß
var
datei: TSearchRec; a: integer; s: string; begin s := 'c:\*.*'; ListView1.Items.Clear; If FindFirst(s,faAnyFile,datei) = 0 then begin try repeat If datei.Name = '.' then Continue; ListView1.Items.Add; a := ListView1.Items.Count -1; ListView1.Items.Item[a].Caption := datei.Name; ListView1.Items.Item[a].SubItems.Add(InttoStr(datei.size)); ListView1.Items.Item[a].SubItems.Add(DateTimetoStr(FileDateToDateTime(datei.time))); If datei.Attr and fadirectory > 0 then begin If datei.name <> '..' then ListView1.Items.Item[a].ImageIndex := 1 else ListView1.Items.Item[a].ImageIndex := 2; end else ListView1.Items.Item[a].ImageIndex := 0; until Findnext(datei) <> 0; finally FindClose(datei); end; end; by Daniel B;Code-Form. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:00 Uhr. |
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