Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi routine aendern(speichern in listbox>speichern in hashtable) (https://www.delphipraxis.net/135418-routine-aendern-speichern-listbox-speichern-hashtable.html)

nimmersattXD 10. Jun 2009 14:29


routine aendern(speichern in listbox>speichern in hashtab
 
Hallo zusammen!

ich habe mal wieder ein problem ;)

ich habe im EasyDelphiHelper eine schoene routine gefunden, die rekursiv nach dateien in ordnern sucht:

Delphi-Quellcode:

procedure GetFilesInDirectory(Directory: String; const Mask: String;
                              List: TStrings;
                              WithSubDirs, ClearList: Boolean);

procedure ScanDir(const Directory: String);
var
  SR: TSearchRec;
begin
  if FindFirst(Directory + Mask, faAnyFile - faDirectory, SR) = 0 then try
    repeat
      List.Add(Directory+SR.Name)
    until FindNext(SR) <> 0;
  finally
    FindClose(SR);
  end;

  if WithSubDirs then begin
    if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then try
      repeat
        if ((SR.attr and faDirectory) = faDirectory) and
           (SR.Name <> '.') and (SR.Name <> '..') then
          ScanDir(Directory + SR.Name + '\');
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
  end;
end;

begin
  List.BeginUpdate;
  try
    if ClearList then
      List.Clear;
    if Directory = '' then Exit;
    if Directory[Length(Directory)] <> '\' then
      Directory := Directory + '\';
    ScanDir(Directory);
  finally
    List.EndUpdate;
  end;
end;
die ergebnisse speicher ich in listboxes:

Delphi-Quellcode:

procedure TForm1.BtnSearchPicClick(Sender: TObject);
var direct:string;
begin
direct:=EdpathP.Text;

GetFilesInDirectory2(direct,'*.jpg',LiBoPathOfPics.Items,true,true);
GetFilesInDirectory2(direct,'*.png',LiBoPathOfPics.Items,true,false);
GetFilesInDirectory2(direct,'*.pdf',LiBoPathOfPics.Items,true,false);
GetFilesInDirectory2(direct,'*.bmp',LiBoPathOfPics.Items,true,false);
GetFilesInDirectory2(direct,'*.gif*',LiBoPathOfPics.Items,true,false);

GetFilesInDirectory1(direct,'*.jpg',LiBoPic.Items,true,true);
GetFilesInDirectory1(direct,'*.png',LiBoPic.Items,true,false);
GetFilesInDirectory1(direct,'*.pdf',LiBoPic.Items,true,false);
GetFilesInDirectory1(direct,'*.bmp',LiBoPic.Items,true,false);
GetFilesInDirectory1(direct,'*.gif*',LiBoPic.Items,true,false);

LbPic.Caption:=(IntToStr(LiBoPic.Count));

end;
ihr seht ich suche nach bildern!

so nun hab ich aber von meinem chef erfahren das mein programm mit hashtabellen viel schneller sein wuerde. nach ein bisschen suchen habe ich auch eine schoene unit csDictionary.pas von alzaimar gefunden.

Ich hab zuerst versucht mit einer zaehlschleife einfach alle items der listbox in die hashtabelle zu laden, aber es sind inkompatible typs pointer und string. Ich weiss das es am schnellsten waer wenn ich es anstatt in die listbox lade gleich in eine hashtabelle, leider weiss ich nicht so recht wie ich die routine umstellen soll!

kann mir da vielleicht jemand helfen?

alzaimar 10. Jun 2009 14:46

Re: routine aendern(speichern in listbox>speichern in has
 
Verwende den Dateinamen als Key und 'nil' für 'Data'. Die Unit stellt ein Wörterbuch dar, bzw. einen Container, der zu einem String (Key) Informationen (Data) liefert.

Wesentlich schneller geht das dann aber auch nicht, denn eine StringList ist schon recht flott. Du musst bei den ListBox.items nur daran denken, 'BeginUpdate' VOR und 'EndUpdate' NACH dem Aufruf aufzurufen, denn sonst wird die Listbox bei jeder Einfügeoperation nue gezeichnet.

nimmersattXD 10. Jun 2009 14:53

Re: routine aendern(speichern in listbox>speichern in has
 
mmh ich wollte eigentlich das ganze ohne listboxes machen und mit der GetFilesInDirectory() routine gleich in einer hashtabelle speichern! Da die routine aber mit TStrings arbeitet und das woerterbuch mit strings oder integers, muss ich sie aendern, oder?

himitsu 10. Jun 2009 14:54

Re: routine aendern(speichern in listbox>speichern in has
 
ich würde es garnicht erst in eine ListBox eintragen, sondern eine TStringList verwenden und diese dann für die HashList auslesen und an die ListBox übergeben.

oder gleich List: TStrings; durch die Hashlist ersetzen.


PS: was sollst du denn, laut Chäffe, damit beschleunigen können?
soeine Liste macht ja wirklich nur viel sinn, wenn du in der Liste etwas suchen willst,

also wenn die Liste entweder sehr groß ist oder du sehr schnell viel finden willst/mußt.

nimmersattXD 10. Jun 2009 14:59

Re: routine aendern(speichern in listbox>speichern in has
 
um das mal zu erklaeren: ich soll ein programm machen, das zum einen die bilder in einem ordner sucht und dann die urls von allen bildern die in htmls, htmlms und jsps auftreten. beides wird dann von dem programm verglichen, um so rauszufinden welche bilder noch benutzt werden und welche nicht.

ich hab das alles mit listboxes realisiert, also mit den namen der bilder die in den ordnern gefunden wurde und eine mit den namen die in den htmls gefunden wurden, die items hab ich dann einfach verglichen ... das geht schon ganz schnell wie ich finde, aber mein chef meinte hashtables sind wesentlich schneller im finden und so ...

himitsu 10. Jun 2009 15:10

Re: routine aendern(speichern in listbox>speichern in has
 
wenn du die VCL wegläßt und direkt TStringList verwendest, bekommst du auch noch schon "etwas" Zeit raus.


um wieviele Bilder handelt es sich denn, so im Durchschnitt
und wie schnell läuft es inzwischen?


ansonsten kommst du schneller, wenn du die Hashlist direkt in die Suchmethode reinbaust

bzw. darin gleich sofort das gesuchte vergleichst und und dann direkt di Liste mit den ungenutzten Bildern erstellst.

nimmersattXD 10. Jun 2009 15:15

Re: routine aendern(speichern in listbox>speichern in has
 
also es handelt sich um etwa 7600 bilder, aber da kommen viele doppelt vor ... noch ein grund warum ich hashlists benutzten wollte, um bevor ich ein bild hinzufuege erstmal suche ob es das nich schon in der liste gibt.

und die suchroutine mit hashlists umzubauen war ja genau meine idee, leider weiss ich nicht genau wie ich das anstellen soll ... deswegen das thema!

himitsu 10. Jun 2009 15:48

Re: routine aendern(speichern in listbox>speichern in has
 
Delphi-Quellcode:
procedure GetFilesInDirectory(const Directory, Mask: String;
    List: TStringDictionary; WithSubDirs, ClearList: Boolean);

  procedure ScanDir(const Directory: String);
    var
      SR: TSearchRec;

    begin
      if FindFirst(Directory + Mask, faAnyFile - faDirectory, SR) = 0 then
        try
          repeat
            //if not List.Contains(Directory + SR.Name) then
              List.Add(Directory + SR.Name);
          until FindNext(SR) <> 0;
        finally
          FindClose(SR);
        end;

      if WithSubDirs then begin
        if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then try
          repeat
            if ((SR.attr and faDirectory) = faDirectory) and
               (SR.Name <> '.') and (SR.Name <> '..') then
              ScanDir(Directory + SR.Name + '\');
          until FindNext(SR) <> 0;
        finally
          FindClose(SR);
        end;
      end;
    end;

  begin
    if ClearList then
      List.Clear;
    if Directory = '' then Exit;
    ScanDir(IncludeTrailingPathDelimiter(Directory));
  end;
Das ganze könnte man dann noch so optimieren, das gleich mehere Masken übergeben werden könnte,
man nur noch eine Suchschleife in der Funktion hat und selber filtert.
Zusätzlich muß die Suchfunktion dann auch nur noch einmal aufgerufen werden.

[edit]
Prüfung auf doppelte Einträge wieder rausgemacht (auskommentiert), denn Doppeltes kann hier ja nicht vorkommen :angel2:


[add]
http://www.delphipraxis.net/internal...034817#1034817
Delphi-Quellcode:
procedure GetFilesInDirectory(const Directory, Mask: String;
    List: TStringDictionary; WithSubDirs, ClearList: Boolean);

  procedure ScanDir(const Directory: String);
    var
      SR: TSearchRec;

    begin
      if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then try
        repeat
          if (SR.Name <> '.') and (SR.Name <> '..') then
            if SR.attr and faDirectory <> 0 then
            begin
              if WithSubDirs then
                ScanDir(Directory + SR.Name + '\')
            end
            else if MatchText(Mask, SR.Name, False) then
              List.Add(Directory + SR.Name);
        until FindNext(SR) <> 0;
      finally
        FindClose(SR);
      end;
    end;

  begin
    if ClearList then
      List.Clear;
    if Directory <> '' then
      ScanDir(IncludeTrailingPathDelimiter(Directory));
  end;



GetFilesInDirectory(direct, '*.jpg|*.png|*.pdf|*.bmp|*.gif*', Hashlist, True, True);

nimmersattXD 10. Jun 2009 16:17

Re: routine aendern(speichern in listbox>speichern in has
 
mmh war ja ganz leicht :)

leider bekomm ich jetzt ne fehlermeldung wenn ich auf den button klicke:

Access violation at address ... in module '... .exe'. write to address .... .

himitsu 10. Jun 2009 16:29

Re: routine aendern(speichern in listbox>speichern in has
 
also, ich hab den Code jetzt nicht getestet ... hab's nur so hingetippt und bin einfach davon ausgegangen, daß er so läuft :oops:


Hast du mal gedebugt und geschaut wo es knallt?

und du hast auch die Liste erstellt? :angel2:
Delphi-Quellcode:
List := TStringDictionary.Create;


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:09 Uhr.
Seite 1 von 5  1 23     Letzte »    

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