Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - routine aendern! (effizienter ;))


nimmersattXD - Fr 19.06.09 13:34
Titel: routine aendern! (effizienter ;))
hallo!

ich hab schon in einem anderen forum gefragt aber da bekomm ich leider zur zeit keine antwort, da es jedoch meine arbeit is weiterzumachen, frag ich jetzt hier vllt koennt ihr mir ja helfen!

also ich hab eine suchroutine, die dateien in ordnern und unterordner sucht:

Delphi-Quelltext
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:
procedure GetFilesInDirectory(Directory: Stringconst 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
      List.Add(SR.Name,nil);
    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;

...
//aufruf der routine
procedure TForm1.BtnSearchPicClick(Sender: TObject); //zum finden der Bilder in Ordner
var direct:string;
begin
direct:=EdpathP.Text;
hashpic:=TStringDictionary.Create;

if not (EdpathP.Text=''then
 begin
 GetFilesInDirectory(direct,'*.jpg',hashpic,true,true);
 GetFilesInDirectory(direct,'*.png',hashpic,true,false);
 GetFilesInDirectory(direct,'*.pdf',hashpic,true,false);
 GetFilesInDirectory(direct,'*.bmp',hashpic,true,false);
 GetFilesInDirectory(direct,'*.gif*',hashpic,true,false);
 end
else ShowMessage('Please, insert the directory paths first!');

LbPic.Caption:=inttostr(hashpic.TotalCount);

end;


im andern forum hat man mir gesagt das es wesentlich besser waere wenn ich die endungen in einem array speicher und die routine nur einmal aufrufe. daraufhin hab ich meine routine geaendert, leider funktioniert jetzt gar nichts mehr :( auserdem glaube ich nicht das das genau das war was die anderen eigentlich meinten um die ordner nicht jedesmal aufs neue zu durchsuchen!


Delphi-Quelltext
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:
procedure GetFilesInDirectory(Directory: Stringconst Mask: Array of String;
                              List: TStringDictionary;
                              WithSubDirs, ClearList: Boolean);

procedure ScanDir(const Directory: String);
var
  SR: TSearchRec;
  i:integer;
begin
for i:=1 to 5 do
begin
  if FindFirst(Directory + Mask[i], faAnyFile - faDirectory, SR) = 0 then try
    repeat
      List.Add(SR.Name,nil);
    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;
end;

begin
    if ClearList then
      List.Clear;
    if Directory = '' then Exit;
    ScanDir(IncludeTrailingPathDelimiter(Directory));
end;

....

procedure TForm1.BtnSearchPicClick(Sender: TObject); //zum finden der Bilder in Ordner
var direct:string;
    PicEnds: array[1..5of string;
begin
direct:=EdpathP.Text;
hashpic:=TStringDictionary.Create;

PicEnds[1]:='*.jpg';
PicEnds[2]:='*.png';
PicEnds[3]:='*.pdf';
PicEnds[4]:='*.bmp';
PicEnds[5]:='*.gif';

if not (EdpathP.Text=''then GetFilesInDirectory(direct,picends,hashpic,true,true)
else ShowMessage('Please, insert the directory paths first!');

LbPic.Caption:=inttostr(hashpic.TotalCount);

end;


kann mir damit jm helfen?? :roll:


Delete - Fr 19.06.09 13:53

Wieso geht Deine Schleife von 1 bis 5? Wie kommst Du auf diese Werte?


nimmersattXD - Fr 19.06.09 13:56

weil ich nach 5 datei-endungen suche und deswegen ein array von 1-5 hab.


Delete - Fr 19.06.09 14:02

Nein, das hast Du nicht, Du hast ein Array von 0 bis High(Array).


nimmersattXD - Fr 19.06.09 14:08


Delphi-Quelltext
1:
2:
3:
procedure GetFilesInDirectory(Directory: Stringconst Mask: Array[1..5of String;
                              List: TStringDictionary;
                              WithSubDirs, ClearList: Boolean);


das geht aber auch nicht :(


elundril - Fr 19.06.09 14:12

ja, is klar, weil arrays als parameter immer dynamisch sind!! das heißt du wirst wohl nicht drum rum kommen dir dynamische arrays mal genau anzusehen!

lg elundril


nimmersattXD - Fr 19.06.09 14:27

so hab mal nachgeguckt, das heisst ich muesste das in etwa so aendern oder?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure GetFilesInDirectory(Directory: Stringconst Mask: Array of String;                              List: TStringDictionary;                              WithSubDirs, ClearList: Boolean);procedure ScanDir(const Directory: String);

var  SR: TSearchRec;
      i:integer;
begin
SetLength(Mask,5);
for i:=0 to 4 do 
begin
...


da bekomm ich den fehler: incompatible types


Delete - Fr 19.06.09 14:32


Delphi-Quelltext
1:
for i := Low(Mask) to High(Mask) do                    


nimmersattXD - Fr 19.06.09 14:37

ok das hab ich auch grad gefunden :)

nun funzt das programm leider immernoch nicht wieder, als ich die such routine vorher "einfach" einzeln aufgerufen hab hats noch funktionier :( ... warum geht das nicht?

der alte quelltext ist auch in meinem ersten post!


Delete - Fr 19.06.09 14:43

Lass Dir doch in der Schleife mal Mask[i] ausgeben, dann siehst Du es vielleicht.


nimmersattXD - Fr 19.06.09 14:58

mmh voll komisch, wollt grad ne listbox fuer die ausgabe machen, aber ich komm an keine einzige komponente in der procedure!?


Delete - Fr 19.06.09 15:01

Es ist ja auch eine Procedure und keine Methode Deines Formulars. Du könntest aber aus List TStrings machen und die Items der Listbox in diesem Parameter übergeben.


nimmersattXD - Fr 19.06.09 15:12

das muss ich doch dann aber auserhalb der procedure machen, wenn ich nich an ie komponente rankomme oder?


jaenicke - Fr 19.06.09 15:15

Wie wäre es, wenn du einmal in die Library schaust...
Da gibts das nämlich bereits fertig...
http://www.delphi-library.de/viewtopic.php?p=124921


Delete - Fr 19.06.09 15:39

Kleine Bemerkung noch am Rande (war mir vorher gar nicht aufgefallen):
Zitat:

Delphi-Quelltext
1:
faAnyFile - faDirectory                    

Das ist pöhse! Sicherer ist es so:

Delphi-Quelltext
1:
faAnyFile and not faDirectory                    


nimmersattXD - Fr 19.06.09 15:51

wusste gar nich das es sowas hier schon gibt, in dem andern forum gabs das zumindest nicht.


jetzt hab ich aber das problem, dass ich in hashtables speichere, wie muss ich die routine umschreiben, dass es funst? (meine ist noch nichts vollstaendig :-()


Delphi-Quelltext
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:
procedure GetAllFilesEM(Path, ExtMask: String; List: TStringDictionary;
  SubFolder: Boolean);
var
  Attrib, k: Integer;
  Search: TSearchRec;
begin
  Attrib := faArchive + faReadOnly + faHidden;


  if Path[Length(Path)] <> '\' then Path := Path + '\';


  with TStringList.Create do
  try
    CommaText := ExtMask;

 
    for k := 0 to Count - 1 do
    if FindFirst(Path + '*.' + Strings[k], Attrib, Search) = 0 then  
      repeat
        List.Add(AnsiUpperCase(Path + Search.Name,nil));
      until FindNext(Search) <> 0;


    FindClose(Search);  
  finally Free end;


  if SubFolder then  
  begin
    if FindFirst(Path + '*.*', faDirectory, Search) = 0 then  
    begin
      repeat  
        if ((Search.Attr and faDirectory) = faDirectory) and
          (Search.Name[1] <> '.'then
          GetAllFilesEM(Path + Search.Name, ExtMask, List, SubFolder);
      until FindNext(Search) <> 0;


      FindClose(Search);  
    end;
  end;
end{Popov}


//aufruf:

procedure TForm1.BtnSearchPicClick(Sender: TObject); //zum finden der Bilder in Ordner
var direct:string;
begin
direct:=EdpathP.Text;
hashpic:=TStringDictionary.Create;

if not (EdpathP.Text=''then GetAllFilesEM(direct,'jpg,png,pdf,bmp,gif',hashpic,true);
else ShowMessage('Please, insert the directory paths first!');

LbPic.Caption:=inttostr(hashpic.TotalCount);

end;


Delete - Fr 19.06.09 15:56

Wenn Du mit dem anderen Forum die DP meinst, da gibt es das auch ;). Und schau Dir die Add-Methode Deiner HashList noch einmal genauer an, dann kannst Du den Code auch anpassen (nach kurzem Drüberschauen ist das wahrscheinlich nur ein Klammerfehler).


nimmersattXD - Fr 19.06.09 16:00

ja ich mein die dp, hatte da auch die suchfunktion genutzt ... mmh vllt bin ich auch zu bloed dafuer


Delete - Fr 19.06.09 16:04

Zitat:

Delphi-Quelltext
1:
List.Add(AnsiUpperCase(Path + Search.Name,nil));                    

->

Delphi-Quelltext
1:
List.Add(AnsiUpperCase(Path + Search.Name),nil);                    

So sollte es stimmen, also doch Klammerfehler ;)


nimmersattXD - Fr 19.06.09 16:11

jop ich habs auch noch gesehen, aber trotzdem danke, is echt nett von dir

aber leider funst mit der routine mein prog nich mehr, un ich hab keine ahnung warum

kannst du vllt mal schnell reingucken?? is bestimmt nur irgendwo ein kleiner fehler, aber ich hab keine ahnung wo :( as waer echt lieb von dir ;)


Delete - Fr 19.06.09 16:13

Sag mir doch erst einmal, was "nicht funzt", dann schau ich mir das auch an.


nimmersattXD - Fr 19.06.09 16:18

stimmt hab ich ganz vergessen, also normalerweise, wenn er alles gefunden hat un die panels gruen sind, wollte er eigentlich die hashpic table mit der hashpicofsit table vergleichen, un wenn etwas uebereinstimmt, das in den listboxes zeigen ... also die tables legt er ja vollstaendig an un die progressbar fuellt sich auch, aber es kommt nichts in den listboxes!?


nimmersattXD - Di 23.06.09 11:00

so hab den fehler gefunden, mein prog funzt nu wieder! aber trotzdem danke