Einzelnen Beitrag anzeigen

Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
205 Beiträge
 
Delphi 10.4 Sydney
 
#1

Directory und Files auflisten

  Alt 12. Aug 2019, 17:49
Hallo Delphi Freunde

ich bin Hobbyprogrammierer und liebe Delphi, manchmal fehlt mir aber die Erfahrung, da ich nicht so oft etwas programmiere.

Im Moment will ich mir eine Liste von Verzeichnissen und Dateien einlesen und später in eine Datenbank schreiben um die Dateien besser suchen, sortieren und kategorisieren zu können.
Zur Zeit habe ich erstmal eine Listbox für die Haupverzeichnisse und ein Grid zum anzeigen der Pfade und Dateinamen angelegt.
Ich benutze Delphi Rio 3.2 und die TMS Komponenten wenn nötig.
Einerseits soll das Einlesen der Dateinamen möglichst effektiv und schnell funktionieren, andererseits will ich aber auch nicht immer wieder das Rad neu erfinden.
Als erstes habe ich mal den Befehl TDirectory.GetDirectories benutzt um die Verzeichnisse einzulesen.
Bei normalen Verzeichnissen flutscht das auch recht gut.
Eine Verzeichnis hat jedoch etwa 14000 Unter-Verzeichnisse und 480000 Dateien, da dauert das einlesen knapp 2 Minuten.
Ich hatte schon überlegt die einzelen Hautverzeichnisse in verschiedenen Threads durchsuchen zu lassen, da das Formular mit "keine Rückmeldung" einige Zeit einfriert, bis dieses große Verz. gelesen worden ist.

1. Bringt es überhaupt etwas mit mehreren Tasks die Verz. gleichzeitig durchsuchen zu lassen ? (Dateien liegen auf einem NAS mit normaler Festplatte)
2. Gibt es einen Befehl der die Größe eines Verzeichnises anzeigt ohne das ganze Verz. zu durchsuchen ? (Um festzustellen wo es sich lohnt zu optimieren)
3. Sind selbstgeschriebene Routinen mit FindFirst,FindNext schneller ?
4. Gibt es auch eine TMS-Komponente die das machen kann, ohne was anzuzeigen wie TAdvTreeView oder TAdvDirectoryList und sind die schneller als GetDirectory ?

Hier etwas Code den ich dazu geschrieben habe:

Delphi-Quellcode:
procedure TForm1.btnStartClick(Sender: TObject);
var
  // SearchResult
  MainVerz: TStringDynArray;
  I: Integer;
  // var i:Integer;
  SearchResult: TStringDynArray;
  StartTime: TTime;
begin
  Grid.RowCount := 1000; // High(SearchResult);
  Grid.FixedCols := 1;
  Grid.ColCount := 3;
  Grid.StartUpdate;
  AktLine := 1;

  // Alle Hauptverzeichnisse einlesen und dann pro Verz. eine Suche ausführen in eigenem Thread
  MainVerz := TDirectory.GetDirectories('Y:\Dateien\', TSearchOption.soTopDirectoryOnly, nil);

  for j := 0 to High(MainVerz) do
  begin
    ListBox1.Items.Add(MainVerz[j]);
    try
      Begin
        // Einlesen der Dateien ab dem Verz[j]
        StartTime := Now();
        SearchResult := TDirectory.GetFiles(MainVerz[j], '*.pdf', TSearchOption.soAllDirectories);
        for I := Low(SearchResult) to High(SearchResult) do
        begin
          if SearchResult[I] <> 'then
          begin
            Grid.Cells[1, AktLine] := ExtractFilename(SearchResult[I]);
            Grid.Cells[2, AktLine] := ExtractFilePath(SearchResult[I]);
            inc(AktLine);
          end;
        end;
        TaskStatus[j] := True;
        ListBox1.Items.Add(' Zeit: ' + TimeToStr(Now - StartTime));
        // Application.ProcessMessages;
      End;
    except
      { Catch the possible exceptions }
      MessageDlg('Incorrect path or search mask', mtError, [mbOK], 0);
      Exit;
    end;

  end;

  Grid.RowCount := AktLine;
  Grid.AutoSizeCol(1);
  Grid.AutoSizeCol(2);
  Grid.SortSettings.IgnoreCase := True;
  Grid.Sort(1, sdAscending);
  Grid.SortSettings.Show := True;
  Grid.EndUpdate;
end;
In der "for I := Low(SearchResult) to High(SearchResult) do" Schleife soll später noch mehr ausgewertet werden (Datum,Dateigröße usw.)
Abwägen zwischen Geschwindigkeit und Einfachheit.
Wenn es bei 2 Minuten Dauer 10 Sekunden mehr oder weniger sind ist das nicht viel, aber den Minutenbereich möchte ich schon umgehen wenn möglich.
Wenn schon mit threads gearbeitet werden muss dachte ich an "OmniThreadLibrary".
Ein Thread ist ja nicht schlimm aber mehrere, damit es sich auch lohnt (CPU Cores ausnutzen) das ist ohne die Lib schon schwierig, wie ich festgestellt habe.

Geändert von Smiley (12. Aug 2019 um 17:52 Uhr) Grund: schreibfehler entdeckt
  Mit Zitat antworten Zitat