So, lange genug gewartet. Jetzt hole
ich mir den Credit.
Basierend auf diesem
Beitrag habe ich einfach mal die Routine überarbeitet und auch ein wenig mit der bedingten Compilierung herumgespielt. Es wird hier vorausgesetzt, dass Pfad, Datum/Zeit und Dateiname in drei verschiedene Stringlisten (= 3 Listboxen) eingetragen werden sollen. Ich glaube aber nicht, dass es schwer ist, die Ausgabe in eine Listbox, ListView, ... umzuleiten ... Ist nur Software-Anpassung.
- Wie gehabt: der Formatstring für Datum und Uhrzeit ist zwar da, wird aber nicht benutzt. Er ist deaktiviert; Datum und Zeit werden nach den Einstellungen des Anwenders formatiert!
- Außerdem habe ich zwei Varianten eingebaut: seit vergangenen TurboPASCAL-Tagen verwende ich eigentlich immer while. Ich habe aber (nicht erst seit lambrucos Code) gesehen, dass viele lieber repeat benutzen. Wer sich also mit while nicht anfreunden kann, entfernt den Punkt in der Zeile
Delphi-Quelltext
und die Prozedur arbeitet -dank bedingter Compilierung!- künftig mit while. Mich hat interessiert, ob das nun schneller ist. Mein Fazit: eigentlich nicht. Aber sei´s drum.
- Außerdem ist standardmäßig die Zählung von Dateien und Ordnern deaktiviert. Wer später eine Meldung ausgeben will, der entfernt auch den Punkt in der Zeile:
Delphi-Quelltext
Im Beispielaufruf kommt später der Rest (sprich: die Anzeige der Dialogbox, usw.)
- Zu guter Letzt ist zu beachten, dass das Arbeitsverzeichnis (das durchsucht werden soll) vor dem Aufruf der Prozedur zu setzen ist. Meine Pfadvariable "orgpath" im Prozedurkopf wird nicht verändert. Ich hab´s mir halt so angewöhnt. Sorry.

Hier nun die Funktion:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114:
|
const szFormat = 'yyyy/mm/dd hh:nn:ss';
{$IFDEF DEBUG_SHOWTIME} var iFile : integer = 0; iFolder : integer = 0; dwStart : dword; {$ENDIF}
procedure FindFiles(const orgpath: string; const FindMask: TStringList; ResultPath, ResultDateTime, ResultFiles: TStrings; const fUseList:boolean=false); var path : string; {$IFNDEF USE_REPEAT} res : integer; {$ENDIF} ds : TSearchRec; begin if(orgpath = '') or (FindMask = nil) or (FindMask.Count = 0) or (ResultPath = nil) or (ResultDateTime = nil) or (ResultFiles = nil) then exit; GetDir(0,path);
{$IFDEF USE_REPEAT} if(FindFirst('*.*',faAnyFile,ds) = 0) then repeat {$ELSE} res := FindFirst('*.*',faAnyFile,ds); while(res = 0) do begin {$ENDIF} if(ds.Attr and faDirectory = 0) and (ds.Name <> '.') and (ds.Name <> '..') then begin {$IFDEF DEBUG_SHOWTIME} inc(iFile); {$ENDIF}
if((not fUseList) and (FindMask.IndexOf(ExtractFileExt(ds.Name)) = -1)) or ((fUseList) and (FindMask.IndexOf(ExtractFileExt(ds.Name)) <> -1)) then begin ResultPath.Add(path);
ResultDateTime.Add(FormatDateTime('' , FileDateToDateTime(ds.Time)));
ResultFiles.Add(ds.Name); end;
end; {$IFDEF USE_REPEAT} until(FindNext(ds) <> 0); {$ELSE} res := FindNext(ds); end; {$ENDIF} FindClose(ds);
{$IFDEF USE_REPEAT} if(FindFirst('*.*',faDirectory,ds) = 0) then repeat {$ELSE} res := FindFirst('*.*',faDirectory,ds); while(res = 0) do begin {$ENDIF} if(ds.Attr and faDirectory <> 0) and (ds.Name <> '.') and (ds.Name <> '..') then begin {$IFDEF DEBUG_SHOWTIME} inc(iFolder); {$ENDIF}
ChDir (ds.Name); FindFiles(orgPath, FindMask, ResultPath, ResultDateTime, ResultFiles, fUseList); end; {$IFDEF USE_REPEAT} until(FindNext(ds) <> 0); {$ELSE} res := FindNext(ds); end; {$ENDIF} FindClose(ds);
if(CompareText(path,orgpath) <> 0) then ChDir('..'); end; |
Und jetzt der Beispielaufruf in einem Buttonklick:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
| procedure TForm1.Button1Click(Sender: TObject); {$IFDEF DEBUG_SHOWTIME} const szActionText : array[boolean]of string = ('Der Ausschluss von','Die Suche nach'); {$ENDIF} var fm : TStringList; fIncludeFiles : boolean; szHomePath : string; begin fm := TStringList.Create; if(fm <> nil) then try fm.Add('.html'); fm.Add('.htm'); fm.Add('.shtml');
ListBox1.Clear; ListBox2.Clear; ListBox3.Clear; ListBox1.Items.BeginUpdate; ListBox2.Items.BeginUpdate; ListBox3.Items.BeginUpdate;
{$IFDEF DEBUG_SHOWTIME} iFile := 0; iFolder := 0; dwStart := GetTickCount; {$ENDIF}
szHomePath := GetCurrentDir;
fIncludeFiles := FALSE;
SetCurrentDir('d:\'); FindFiles ('d:\', fm, Listbox1.Items, Listbox2.Items, Listbox3.Items, fIncludeFiles );
SetCurrentDir(szHomePath);
{$IFDEF DEBUG_SHOWTIME} dwStart := GetTickCount - dwStart; {$ENDIF}
ListBox1.Items.EndUpdate; ListBox2.Items.EndUpdate; ListBox3.Items.EndUpdate;
{$IFDEF DEBUG_SHOWTIME} ShowMessage(Format( '%s %d Dateitypen benötigte %d msec bei %d Dateien und %d Ordnern.', [szActionText[fIncludeFiles],fm.Count,dwStart,iFile,iFolder])); {$ENDIF} finally fm.Free; end; end; |
Damit würden alle Dateien aufgelistet werden -
außer HTML, HTM und SHTML. Wer stattdessen
nur HTML-, HTM- und SHTML-Dateien anzeigen lassen möchte, ändert lediglich die Bool-Variable:
Delphi-Quelltext
1:
| fIncludeFiles := TRUE; |
Das war´s. Sieht da wer durch?
(btw: Ich habe mal meine C-Partition (Win98) nach HTML, HTM und SHTML scannen lassen. Wie gehabt kam es zur schon mal erwähnten "Eigenart" von FindFirst und Co. Beim allerersten Start (quasi nach dem Hochfahren des Rechners) brauchte die obige Funktion ~10 Sekunden, um 21.188 Dateien und 1.867 Ordner zu durchsuchen. Beim zweiten Versuch, gleich danach!, nur noch ~4 Sekunden.
Erklären kann ich es nicht. Ich kann nur raten, dass die Ergebnisse irgendwie indiziert oder auf andere Art "gemerkt" werden, sonst käme es nicht zu einem Zeitunterschied von 9 Sekunden.)
Mit Dank an lambruco für die Idee.