![]() |
Delphi-Version: 2007
TSearchRec.Findfirst, findnext Alternative
Kennt jemand eine schnellere TSearchRec.Findfirst, findnext Alternative ?
|
AW: TSearchRec.Findfirst, findnext Alternative
Du kannst das auch per API machen (
![]() ![]() |
AW: TSearchRec.Findfirst, findnext Alternative
Is the same.
Delphi-Quellcode:
function FindMatchingFile(var F: TSearchRec): Integer;
var LocalFileTime: TFileTime; begin with F do begin while FindData.dwFileAttributes and ExcludeAttr <> 0 do if not FindNextFile(FindHandle, FindData) then begin Result := GetLastError; Exit; end; FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime); FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo); Size := FindData.nFileSizeLow or Int64(FindData.nFileSizeHigh) shl 32; Attr := FindData.dwFileAttributes; Name := FindData.cFileName; end; Result := 0; end; function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer; const faSpecial = faHidden or faSysFile or faDirectory; begin F.ExcludeAttr := not Attr and faSpecial; F.FindHandle := FindFirstFile(PChar(Path), F.FindData); if F.FindHandle <> INVALID_HANDLE_VALUE then begin Result := FindMatchingFile(F); if Result <> 0 then FindClose(F); end else Result := GetLastError; end; function FindNext(var F: TSearchRec): Integer; begin if FindNextFile(F.FindHandle, F.FindData) then Result := FindMatchingFile(F) else Result := GetLastError; end; procedure FindClose(var F: TSearchRec); begin if F.FindHandle <> INVALID_HANDLE_VALUE then begin Windows.FindClose(F.FindHandle); F.FindHandle := INVALID_HANDLE_VALUE; end; end; |
AW: TSearchRec.Findfirst, findnext Alternative
Schneller geht nur
- die MFT auslesen (bei NTFS) - mit Backuprechten das Verzeichnis direkt auslesen und den Inhalt selber parsen (hier brauchst'e dann Wissen über die Interna von ausreichend verschiedenen Dateisystemen) schneller, aber einfacher = Austausch der HDD (SDD) |
AW: TSearchRec.Findfirst, findnext Alternative
Wie machen es denn die ShellCtrls ?
|
AW: TSearchRec.Findfirst, findnext Alternative
Zitat:
Die gehn über ![]() |
AW: TSearchRec.Findfirst, findnext Alternative
Ich hab' mir die ShellCtrls jetzt auch mal näher angesehen. Die laden immer nur den nächsten Level in das TreeView rein (keine Rekursion). Deshalb sind diese (scheinbar) schneller, liegt weniger an findfirst und Co.. ShellTreeView1.Items[0].Expand(true) dauert deshalb auch sehr lange (lädt dann die fehlenden Items nach).
|
AW: TSearchRec.Findfirst, findnext Alternative
Das macht übrigens der Windows Explorer auch nicht anders.
|
AW: TSearchRec.Findfirst, findnext Alternative
So geht's eigentlich ganz gut, nur bisschen doof, daß dann erst mal nicht angezeigt wird, ob der Ordner Unterordner hat.
Delphi-Quellcode:
procedure GetNextLevelNodeDirs(const ADirectory: String; var ATree: TTreeView; const Start: TTreeNode);
var S: TSearchRec; R: integer; N: TTreeNode; begin R:= FindFirst(IncludeTrailingPathDelimiter(ADirectory)+'*.*', faDirectory, S); while R = 0 do begin if ((S.Attr and faDirectory) <> 0) then if ((S.Name <> '.') and (S.Name <> '..')) then if not N.HasChildren then N:= ATree.Items.AddChild(Start, S.Name); R:= FindNext(S); end; Findclose(S); end; procedure TForm1.FormCreate(Sender: TObject); var Path: string; begin Path:= 'C:\'; TreeView1.Items.BeginUpDate; GetNextLevelNodeDirs(Path, TreeView1, TreeView1.Items.AddChild(Nil, Path)); TreeView1.Items.EndUpDate; TreeView1.Items[0].Expand(false); end; function GetTreeNodePath(const ANode: TTreeNode): string; var I: integer; begin if Assigned(ANode) then if Assigned(ANode.Parent) then GetTreeNodePath:= GetTreeNodePath(ANode.Parent)+'\'+ANode.Text else Result:= ANode.Text else Result:= ''; if Result <> '' then Result:= Result+'\'; I:= 1; while I < Length(Result) do begin if (Result[I] = '\') and (Result[I+1] = '\') then Delete (Result, I, 1); Inc(I); end; end; procedure TForm1.TreeView1Click(Sender: TObject); var ANode: TTreeNode; begin ANode:= TreeView1.Selected; TreeView1.Items.BeginUpDate; GetNextLevelNodeDirs(GetTreeNodePath(ANode), TreeView1, ANode); TreeView1.Items.EndUpDate; end; procedure TForm1.TreeView1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin TreeView1Click(Sender); end; |
AW: TSearchRec.Findfirst, findnext Alternative
Ich kenne da den Trick, zunächst einmal "Dummy"-Knoten anzulegen, damit auf jeden Fall das "+" angezeigt wird. Wird nun versucht, den Knoten aufzuklappen und der Ordner enthält keine Unterordner, dann wird das Aufklappen abgebrochen und das "+" entfernt. Aber mal etwas anderes zu GetNextLevelNodeDirs: wieso übergibst Du die Treeview als Var-Parameter? Und N ist zumindest beim ersten Scheifendurchlauf nicht initialisiert, es wundert mich ein wenig, dass das nicht knallt.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 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 by Thomas Breitkreuz