Entwickler-Ecke

Open Source Units - SearchTool v3.0.1.1 - schnelles Suchverfahren


Heiko - Sa 24.09.05 14:56
Titel: SearchTool v3.0.1.1 - schnelles Suchverfahren
Für das Gemeinschaftsprojekt [url=http://www.killprocess.de.vu]Killprocess[/url], in dem ich bin, benötigten wir ein schnelles Suchverfahren um Musikdateien für den MP3-Tag-Editor zu finden. Angefangen haben wir mit dem wohl bekanntesten aber langsamen SearchRec, danach fand ich die Unit DriveTools [http://www.delphi-forum.de/viewtopic.php?t=33882&start=0&postdays=0&postorder=asc&highlight=drivetools] von Luckie, wesentlich schnellern war. Da darauf jedoch ein Copyright ist ;) und ich im Projekt so wenig wie möglich externes haben möchte, habe ich mir die Arbeit gemacht, diese Unit umzuschreiben (aber nur die Prozeduren, die ich brauchte). Herausgekommen ist die Unit SearchTools, die einiges dem Programmierer im Vergleich zu der Unit DriveTools vereinfacht, dafür aber einiges nicht bietet, was die Luckies Unit besitzt. So gibt es die Prozedure GetLogicalDrives und die Funktion GetVolumeLabel nicht (dafür kann man ja dann die DT nehmen ;) ). Ich muss aber dazu sagen, das die Prozedur GetLogicalDrives indirekt eingebaut ist. Sprich wenn man als Root den Arbeitsplatz angibt und Rekursiv sucht, sucht er gleich alle Laufwerke ab, wodurch ich auch nach den Laufwerken suchen musste.

Features
enthaltene Features
Auflistung folgt später

geplante Features


abgelehnte Features


Programme die diese Unit verwenden


//EDIT: Versionsänderungen heruasgenommen (im Source enthalten)


Delete - Sa 24.09.05 16:43


Delphi-Quelltext
1:
if FileName='Arbeitsplatz\' then                    

Viel Spass auf Rechnern mit nicht deutschen Windows. ;)

Aber wenn deine Unit schon auf meiner basiert, dann wäre es auch nett, wenn ich zu mindest im Dateiheader erwähnt würde mit mit Verweis auf die ursprüngliche Unit. BTW gibt es eine neue Unit DriveTools: MpuDriveTools mit einer Klasse die den Fortschritt beim Suchen der Dateien anzeigt: http://www.luckie-online.de/Developer/Delphi/Sonstiges/


Heiko - Sa 24.09.05 16:51

Gut das du mich daran erinnerst. Das mit dem Arbeitsplatz wollte ich noch verbessern (habe ich glatt vergessen ;) ). Ein kommentar das es aus der Unit abgeleitet ist kann ich noch hinzufügen (hatte ich nicht gemacht, da doch eine starke Abweichung vorhanden ist).

@MpuDriveTools: Die habe ich schon gesehen, allerdings nützt das mit dem Fortschritssbalken mir nix, da es ein zu großer Performanceverlust bedeutet (wenn ich das machen würde, wäre ich wieder bei der gleichen Performance wie deiner, da ich erst alle ordner suchen müsste). Und beim Projekt, wofür es ja ist, haben wir dafür einen Fortschrittsbalken zum Auslesen von DateiInfos verwendet, da es dort kein (großer) Performanceverlust ist, wenn man noch eine Gauge auf Minimalbetrieb mitbetreibt. Während der Suche mit dem SearchTool habe ich einen endlosen Progressbar genommen, damit man nicht das Gefühl bekommt, das er nix macht, wenn man die festplattenauslastung nicht sieht.


Delete - Sa 24.09.05 17:03

user profile iconHeiko hat folgendes geschrieben:
Ein kommentar das es aus der Unit abgeleitet ist kann ich noch hinzufügen (hatte ich nicht gemacht, da doch eine starke Abweichung vorhanden ist).

Ich habe ja auch geschrieben "wäre nett", aber kein muss. Denn immerhin habe ich teilweise meinen Variablen und Prozedurnamen wieder erkannt. ;)

Zitat:

@MpuDriveTools: Die habe ich schon gesehen, allerdings nützt das mit dem Fortschritssbalken mir nix, da es ein zu großer Performanceverlust bedeutet (wenn ich das machen würde, wäre ich wieder bei der gleichen Performance wie deiner, da ich erst alle ordner suchen müsste). Und beim Projekt, wofür es ja ist, haben wir dafür einen Fortschrittsbalken zum Auslesen von DateiInfos verwendet, da es dort kein (großer) Performanceverlust ist, wenn man noch eine Gauge auf Minimalbetrieb mitbetreibt. Während der Suche mit dem SearchTool habe ich einen endlosen Progressbar genommen, damit man nicht das Gefühl bekommt, das er nix macht, wenn man die festplattenauslastung nicht sieht.

Man muss den Fortschritt ja nicht nutzen. Desweiteren bin ich hab eich auch nicht mehr das globale Datei Array drinne, was vorher noch sehr unschön war.


Heiko - Sa 24.09.05 17:17

user profile iconLuckie hat folgendes geschrieben:
user profile iconHeiko hat folgendes geschrieben:
Ein kommentar das es aus der Unit abgeleitet ist kann ich noch hinzufügen (hatte ich nicht gemacht, da doch eine starke Abweichung vorhanden ist).

Ich habe ja auch geschrieben "wäre nett", aber kein muss. Denn immerhin habe ich teilweise meinen Variablen und Prozedurnamen wieder erkannt. ;)

In der version auf meinem PC ist es jetzt dabei, damit man weiß das es deine gibt mit Funktionen, die bei mir nicht drin sind ;).
@Dateinamen: Die meisten habe ich gelassen, da sie schon passend benannt sind und ich einige genau gleich benannt hätte, wie wfd für TWin32FindData ;) (bei zu langen Typen und Namen die ich nicht zufällig so ähnlich drin habe mache ich das manchmal so).


user profile iconLuckie hat folgendes geschrieben:
user profile iconHeiko hat folgendes geschrieben:
@MpuDriveTools: Die habe ich schon gesehen, allerdings nützt das mit dem Fortschritssbalken mir nix, da es ein zu großer Performanceverlust bedeutet (wenn ich das machen würde, wäre ich wieder bei der gleichen Performance wie deiner, da ich erst alle ordner suchen müsste). Und beim Projekt, wofür es ja ist, haben wir dafür einen Fortschrittsbalken zum Auslesen von DateiInfos verwendet, da es dort kein (großer) Performanceverlust ist, wenn man noch eine Gauge auf Minimalbetrieb mitbetreibt. Während der Suche mit dem SearchTool habe ich einen endlosen Progressbar genommen, damit man nicht das Gefühl bekommt, das er nix macht, wenn man die festplattenauslastung nicht sieht.

Man muss den Fortschritt ja nicht nutzen. Desweiteren bin ich hab eich auch nicht mehr das globale Datei Array drinne, was vorher noch sehr unschön war.

Wenn man den nicht nutzt, bringt einem die Unit MpuDriveTools nix, denn dann kann man ja gleich die Unit DT nehmen.
@Globale Variable: Habe ich mit Absicht gelassen, obwohl ich retnyg's Kommentar gelesen habe, damit ich später wieder auf das ausgelesene Zurücklgreifen kann, ohne es etxra zwischenzuspeichern.

PS: Bei Namen nehme ich das ' rein, damit man den Namen vom Fall abgetrennt erkennt ;).


Delete - Sa 24.09.05 17:20

user profile iconHeiko hat folgendes geschrieben:

Wenn man den nicht nutzt, bringt einem die Unit MpuDriveTools nix, denn dann kann man ja gleich die Unit DT nehmen.

Doch, es ist OOP konform und somit einfach sauberer.


Heiko - Sa 24.09.05 17:32

Warum sauberer? Wenn man etwas nicht benötigt (in dem Fall die OOP) und nicht braucht nenne ich das nicht sauberer.


Delete - Sa 24.09.05 18:37

Die globale Variable bleibt unsauber und hier ist sie sogar gefährlich, wenn man vergisst sie zu initialisieren. Und das ist keine Frage von brauchen oder nicht brauchen. Und was hat brauchen oder nicht brauchen damit zu tun, ob namn den Cpde sauber in eine Klasse verpackt oder nicht?


Heiko - Sa 24.09.05 20:06

Wenn man vergisst sie zu initialisieren ist bei meiner Version egal, da er es bei jedem Aufruf selber macht. Und wenn man sie als Parameter übergibt, muss der Programmierer ja schließlich auch dafür sorgen, das sie initialisiert wird, wenn er sie sich global speichert um damit längere Zeit arbeiten zu können.


Heiko - Sa 22.10.05 14:11

So, ich habe jetzt die neue Version fertig (nach dem sie seit einem Tag nach der Veröffentlichung der Version 1 sich in der Beta-Phase befand). Die Neuerungen habe ich oben im ersten Post hingeschrieben.

Hier ist auch meine Performance-Vergleich-Prozedur, damit ihr seht das es ein fairer Vergleich ist ;):


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:
procedure TForm1.Button4Click(Sender: TObject);
var
  StringArray: TStringArray;
  i: Integer;
  Zeit1, Zeit2, StartZeit: Cardinal;
begin
  SetLength(StringArray, 1);
  StringArray[0]:='*.mp3';
  for i:=0 to 1 do
  begin
    SearchTool.SearchFiles('C:\', StringArray, true);
    DriveTools.InitFindAllFiles;
    DriveTools.FindAllFiles('C:\''*.mp3', true);
  end;
  Zeit1:=0;
  Zeit2:=0;
  for i:=0 to 1 do
  begin
    StartZeit:=GetCurrentTime;
    SearchTool.SearchFiles('C:\', StringArray, true);
    inc(Zeit1, GetCurrentTime-StartZeit);

    StartZeit:=GetCurrentTime;
    DriveTools.InitFindAllFiles;
    DriveTools.FindAllFiles('C:\''*.mp3', true);
    inc(Zeit2, GetCurrentTime-StartZeit);
  end;
  ShowMessage('ST: '+IntToStr(Zeit1 div 2)+' ms'+#13+
              'gefundene Dateien: '+IntToStr(SearchTool.cntFoundFiles)+#13+
              'DT: '+IntToStr(Zeit2 div 2)+' ms'+#13+
              'gefundene Dateien: '+IntToStr(DriveTools.cntFoundFiles));
end;


Delete - Sa 22.10.05 15:02

Wie schon im andren Thread geschrieben, es gibt eine neue version: http://www.luckie-online.de/Developer/Delphi/Sonstiges/ -> MpuDriveTools.pas


alzaimar - Sa 22.10.05 15:22
Titel: Re: SearchTool - schnelles Suchverfahren
user profile iconHeiko hat folgendes geschrieben:
... Da darauf jedoch ein Copyright ist ;) und ich im Projekt so wenig wie möglich externes haben möchte, habe ich mir die Arbeit gemacht, diese Unit umzuschreiben (aber nur die Prozeduren, die ich brauchte). Herausgekommen ist die Unit SearchTools, ...

Es geht mich ja eigentlich Nichts an, aber ...
Du kopierst, gibst es auch zu und meinst dann auch, Du wärst gnädig, wenn Du einen Verweis auf den ursprünglichen Programmierer nach dessen Bitten in deiner SW unterbringst. Wow, Echt Klasse. Mit anderen Worten: Du bist nicht selbst drauf gekommen, kopierst schamlos und meinst dann auch noch, es wäre dein geistiges Eigentum. Ich nenn soetwas eine bodenlose Frechheit.

Heiko, Du hast dich gerade in meinen Augen selbst disqualifiziert.

Denk mal drüber nach.


Heiko - Sa 22.10.05 18:44

Jein, das mit dem geistigen Eigentum ist eine zwiespaltige Angelegenheit. Denn ich habe mir bei Luckie die Variante mit dem Suchen abgeguckt, denn meine alte Variante mit SearchRec war echt lahmarschig, was ich benutztern von Programmen wo ich mitarbeite nicht antuen will (5 Min. vs. 5 Sek. ist doch ein gravierender Unterschied). Durch Zufall bin ich dann auf Luckies DriveTools hier im Forum gestoßen die ich dann erstmal verwendet habe (ohne groß eine Ahnung zu haben wie die funktioniert). Jedoch habe ich gleich eine Änderung vorgenommen, die ein paar Zeilen spart, da einige Dinge vorsehbar sind, sprich von TWin32FindData, wenn es einen Ordner gefunden hat, cFileName immer ohne "\" endet. Luckie führt jedoch bei der Rekursion immer zu begin eine Überprüfung des Pfades auf "\" als letztes Zeichen auf und wenn es nicht vorhanden ist setzt er es hinzu. Wie er auf den Gedanken kam war mir sofort klar, denn wenn man die Prozedur aufruft kann man das ja vergessen haben. Wenn die jedoch durch die Rekursion aufgerufen wird, kann man ja eigentlich schon gleich das "\" beim Parameter hinzufügen. Für den Fall das der Programmierer den Fehler beim Aufruf macht, kann man einen Fehler durch eine Überprüfung in einer extra Prozedur gestalten, die dann erst den Suchalgorithmus den Suchalgorithums aufruft.
Nach einiger Zeit der Nutzung habe ich mich dann jedoch gefragt wie die genau funktioniert, da ich keine Ahnung hatte wie die funktionieren soll, da ich kein anderes Verfahren als die mit dem SearchRec kannte, so dass ich angefangen habe mich dort reinzudenken. Beim reindenken sind mir dann gewisse Schwachstellen in der Unit aufgefallen, sprich das er bei einer rekursiven Suche einmal nach der Datei sucht mit dem Filter (was Performance mäßig schnell ist), dann jedoch noch einmal nach allen Dateien sucht und diese dann darauf überprüft ob es ein Ordner ist. Das ist jedoch eine doppelte Durchsuchung der Festplatte Suche nach den Dateien.
Damit war der erste Gedanke einer Umschreibung der Unit entstanden. Nach dem ich die Unit zum ersten mal genutzt hatte, habe ich gleich nachgefragt ob man Luckies Unit auch in Freewareprogrammen verwenden darf, woraufhin er es ausdrücklich zusagte. Daraufhin hatte ich gleich noch einmal nachgefragt ob wir ihn auch in die Aboutbox des Programmes erwähnen sollen, auch wenn ich die Unit ein umschreibe. Daraufhin bekam ich jedoch keine Antwort, wodurch ich mir dahcte das wir ihn Sicherheitshalbe aufnehmen werden. Aber ich hatte dabei gleich einen Gedanken dazu bekommen der mir nicht ganz behagte, sprich ich finde es blöd wenn man ein Programm als Freeware anbeitet, wo in der AboutBox dann 5 Leutchen als Entwickler stehen und dann noch ne ganze Stange von Personen, von denen man Units verwendet hat. Das war dann der Ausschlag die Unit fast komplett umzuschreiben.
Allerdings hatte ich dabei ein Problem: Ich hatte kaum Ahnung von Win-API wo ich mit Handles & Co umgehen muss. Dadurch habe ich nicht eine neue Unit erstellt und so aus freien Stücken angefangen zu entwickeln, sondern habe mir seinen Quelltext kopiert und den dann immer Stück für Stück umgeschrieben, so dass ich immer überprüfen konnte ob sie noch funktioniert (bloß gut, denn manchaml hatte ich dann einen kleinen Denkfehler drin, den ich so schnell gefunden habe).
Dann stand die Unit erstmal, mit noch ein ganz paar Resten von Luckies Quelltext. Da es jedoch für eine Gruppenarbeit ist, habe ich mir dann gedacht gehabt, das ich alles was mit der Suche in die Unit auslaggere, sprich die Überprüfung ob ich überhaupt auf das Laufwerk zugreigen kann und die Suche nach allen Laufwerke bei Übergabe des Arbeitsplatzes,. Und da ich ja sowieso schon eine Prozedur hatte die aufgerufen wird bevor der Suchalgorithmus gestartet wird, konnte ich es ohne Probleme dort einfügen. Dazu kam später die Überprüfung ob der Ordner überhaupt existiert, in dem die Suche gestartet werden soll.
Allerdings gab es dann immernoch eine Stelle dir mir nicht gefallen hat. Und zwar das ich die Prozedur oft hintereinander aufrufen muss, da ich ja nach bis zu 7 Formaten mit einmal suchen will. So habe ich mich nochmal ans Werk gemacht und die Unit weiterumgeschrieben, das er jede Datei gleich auf die Endung überprüft ob die in der Liste steht. So ungefähr war der Verlauf zur v1.0 von der SearchTool.
Als die fertig war habe ich auch gleich BenBE gefragt, ob wir die Unit irgendwie für Omorphia verwenden können, wo er zusagte. Da jedoch eine Suche nur auf Endungen nicht so güstig ist, schrieb ich gleich an einem Filter, der auch Suche mit Sternchen erlaubt und auch genaue Dateinamen. Damit war ich innerhalb von ein paar Stunden fertig, wo viel Zeit im testen Verging - und in der Fehlersuche ;).
Nachdem das funktioniert hat, hatte ich überlegt, ob ich es als v2.0 veröffentliche. In der Zeit hat jedoch schon Luckie mich darauf hingewiesen das die Überprüfung auf Arbeitsplatz nur auf deutschen Windows-Versionen funktioniert, so dass ich die v2.0 doch nicht verlöffentlichte und sie erstmal in den Beta-Status wieder schob. Dann begann die Große Suche nach einer Möglichkeit den "Fehler" auszubessern, jedoch mit keinem Ergebnis was mir so schnell half. In zwischen habe ich es hinbekommen.

Durch den Verlauf entstand erstmal eine so ziemlich vollständige Fehlerbehandlung, aber auch ein Quelltext der inzwischen 275 Zeilen lang ist. Luckies ist jedoch nur 209 Zeilen lang, obwohl er Funktionen anbietet dich ich nicht verwendet habe. Des weiteren kam dazu das ich beim Umschreiben eine ganze Menge ein bisschen anders gelöst habe. Dadurch sind es schätzungsweise noch 20-50 Zeilen Quelltext mit Luckies übereinstimmen, da ich keinen Grund sah die umzuschreiben.
Bei den paar Zeilen Übereinstimmung fand ich es nicht nötig Luckie groß noch zu Erwähnen (nach Wunsch von Luckie habe ich es aber hinzugefügt das sie von ihm abgeleitet ist, obwohl so wenig übereinstimmt noch). Durch die paar Zeilen könnte man sagen zwar sagen das es Diebstahl von geistigen Eigentum ist, aber da sich dabei ja eigentlich nur um etwas aufeinander bauendes handelt (die Verwendung von TWin32FindData) empfinde ich es eigentlich nicht als solchen Diebstahl, da ja der Rest eigentlich von mir stammt, wo sich manchmal allerdings einige Passagen verhindern ließen, wo man denken könnte das von Luckie stammt, was aber meistens nicht stimmt.

Ich hoffe du verstehst jetzt meinen Gedankengang alzaimar ;).

mfg
Heiko


alzaimar - Sa 22.10.05 20:15

Dein Gedankengang wird immer klarer :wink:
Du findest es nicht nötig, den Verfasser des Quelltextes, den Du umgeschrieben hast, zu erwähnen? Du nimmst die Idee und den Gehirnschmalz eines Anderen, lernst daraus und entfernst dann das Copyright. Also, das muss nicht sein. Du bist doch dankbar, das jemand wie Luckie Dir seinen Code zur Verfügung gestellt hat. Ohne diesen Code wärst Du mit deinem Tool nicht da, wo Du jetzt bist, oder? Du hast den Code modifiziert und erweitert, aber, es bleibt letztendlich Luckies Verdienst.

Du hast es doch nicht nötig, mit Danksagungen und Copyrighthinweisen zu sparen.

"Basiert auf dem Code von Luckie und Tipps und Tricks des http://www.delphi.forum.de, Danke an Alle"

So als Tipp.

Na denn, weitermachen :beer:

"Wer sich dankbar zeigt, dem wird auch Dank zuteil"


retnyg - So 23.10.05 06:01

so, ich habe deine unit mal ausgiebig getestet und mit meiner und luckies verglichen.
also:
- die methode, die ordner nicht separat zu scannen bringt nur was bei *.*
- deine unit unterstützt *.* scheinbar nicht :shock: cntFoundfiles = 0
- deine unit unterstützt keine suche nach dateien wie "*bl*.mp3", "slayer", usw
- deine unit liefert keine verzeichnisnamen (wie bei luckie)
- deine unit hat wie luckie's keine möglichkeit, einen fortschritt anzuzeigen
- dafür kann man mehrere "suchbegriffe" übergeben, und die geschwindigkeit ist ziemlich gut, wenn ein resultat kommt...

hier mal meine version, hab da heute den ganzen tag dran rumgewerkelt o0

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:
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:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
unit retFileSearch;

// ============================================================
// done by retnyg @ http://krazz.net/retnyg
//
// optimized version of luckie's findallfiles in drivetools.pas
//
// new: - no init routine needed
//      - no need to check global variables inside the unit
//      - possibility of adding a callback proc for progress update
//      - optimized much
//      - can return also directories

interface

uses windows;

  type tArray = array of string;
  type tfcbfunc = procedure (x:integer;t:tarray);

  function FindAllFiles(RootFolder: string; Mask: stringvar outputArray: TArray; callback: TFCBFunc; Recurse: Boolean = True; ShowDirectories: boolean = false):integer;

implementation

//function PathMatchSpecA(pszFile, pszSpec: String): Boolean; StdCall; External 'SHLWAPI.DLL';

function FindAllFiles(RootFolder: string; Mask: stringvar outputArray: TArray; callback: TFCBFunc; Recurse: Boolean = True; ShowDirectories: boolean = false):integer;
const
  C_STEP   = 128;            // Get Memory after x array entries
  C_DOT    = $0000002E;     // '.'
  C_DOTDOT = $00002E2E;     // '..'
  C_WILDC1 = '*'//: WORD = $2A5C;  // '\*'
  CC_WILDC = $002A2E2A;
  C_WILDC2 = '*.*';//$002A2E2A;     // '\*.*'
  CC_WILDC2 : word = $002A;
  CC_DIRSUFFIX : word = $005C;

  SIZE_OF_WFD = sizeof(Twin32FindData);

var
  fileCount: integer;
  cRoot: array [1..MAX_PATH] of char;
  bMaskIsWildcard: boolean;
  lMask        : integer;

  procedure ParseDir(idx:integer);
  var
    l : integer;
    hFindFile    : THandle;
    wfd          : TWin32FindData;

    procedure Add;
    begin
      if fileCount mod C_STEP = 0 then setlength(OutputArray, filecount + C_STEP);
      setlength( outputArray[fileCount], idx + l);
      move(cRoot,outputArray[fileCount][1], idx);
      move(wfd.cFileName, outputArray[fileCount][idx+1],l);

      if cardinal(@callback) <> 0 then callback(fileCount,outputarray);
      inc(fileCount);
    end;

    procedure SetMask;
    begin
      move(pointer(Mask)^,cRoot[idx+1],lMask+1); // #0 mitkopieren
    end;

  begin
      if (Recurse) or (bMaskIsWildCard) or (pointer(Mask) = nilthen
        pcardinal(@cRoot[idx+1])^ := CC_WILDC
        //pword(@cRoot[idx+1])^ := CC_WILDC2
      else
        SetMask;

      fillchar(wfd,SIZE_OF_WFD,0);

      if (Recurse and not bMaskIsWildCard) or (pointer(Mask) = nilthen begin
        hFindFile := FindFirstFile(@cRoot, wfd);
        if hFindFile <> INVALID_HANDLE_VALUE then
        repeat
            if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY then
            if (pdword(@wfd.cFileName[0])^ <> C_DOT) and
               (pdword(@wfd.cFileName[0])^ <> C_DOTDOT) then
            begin
              l := 0;
              while wfd.cFileName[l] <> #0 do inc(l);
              if ShowDirectories then Add;
              if (pointer(Mask) <> nilor (Recurse) then begin
                move(wfd.cFileName,cRoot[idx + 1],l);
                pword(@cRoot[idx + l + 1])^ := CC_DIRSUFFIX;
                parseDir(idx + l + 1);
              end;
            end;
        until FindNextFile(hFindFile, wfd) = False;
        windows.FindClose(hFindFile);
        if pointer(Mask) <> nil then SetMask;
      end;

      if pointer(mask) <> nil then begin

        hFindFile := FindFirstFile(@cRoot, wfd);
        if hFindFile <> INVALID_HANDLE_VALUE then
        repeat
          l := 0;
          while wfd.cFileName[l] <> #0 do inc(l);
          // die 2 zeilen entsprechen         l := strlen(@wfd.cFileName);
          // sind nun aber inline und unabhängig von sysutils...
          if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> FILE_ATTRIBUTE_DIRECTORY then begin
            //if PathMatchSpecA(string(wfd.cFileName),Mask) then
            Add
          end
          else // isn verz.
            if recurse and bMaskIsWildCard then
              if (pdword(@wfd.cFileName[0])^ <> C_DOT) and (pdword(@wfd.cFileName[0])^ <> C_DOTDOT) then  begin
                if ShowDirectories then Add;
                move(wfd.cFileName,cRoot[idx + 1],l);
                pword(@cRoot[idx + l + 1])^ := CC_DIRSUFFIX;
                parseDir(idx + l + 1);
              end;
        until FindNextFile(hFindFile, wfd) = False
        //else asm int 3 end
        ;
        windows.FindClose(hFindFile);

      end;

      cRoot[idx] := #0;
  end// end proc ParseDir

  var   lRoot: integer;

begin
  fileCount := 0;
  lRoot := length(RootFolder);
  move(pointer(RootFolder)^,cRoot,lRoot+1);
  if cRoot[lRoot] <> '\' then begin
    inc(lRoot);
    cRoot[lRoot] := '\';
    cRoot[lRoot+1] := #0;
  end;
  lMask := length(Mask);
  bMaskIsWildCard := false;
  if lMask = 1 then
    if Mask = C_WILDC1 then
      bMaskIsWildcard := true
    else
  else
    if lMask = 3 then
      if Mask = C_WILDC2 then
        bMaskIsWildcard := true;

  if not (bMaskIsWildCard) and (lMask <> 0then
   if pos(C_WILDC1,Mask) = 0 then begin
     Mask := C_WILDC1 + Mask + C_WILDC1;
     inc(lMask,2);
   end;
  ParseDir(lRoot);
  result := filecount;
  setlength(outputArray, fileCount);
end;



end.


Heiko - So 23.10.05 10:27

user profile iconalzaimar hat folgendes geschrieben:
Ohne diesen Code wärst Du mit deinem Tool nicht da, wo Du jetzt bist, oder?

Ja das stimmt, denn ich kannte die Win-API davor dafür überhaupt nicht.

user profile iconalzaimar hat folgendes geschrieben:
"Basiert auf dem Code von Luckie und Tipps und Tricks des http://www.delphi.forum.de, Danke an Alle"

Das mit dem Delphi-Forum könnte ich noch hinzufügen, allerdings wäre das sehr verbal. Für das was ich gestern bei der v2.0 noch hinzugefügt habe, habe ich glatt vergessen noch ein paar Personen oben zu benennen, sprich Eugen Honeker und Mathias Simmack, da ich mir dort die Art angeguckt habe um die Bezeichnung für den Arbeitsplatz zu bekommen (alleine hätte ich auch nicht gewusst wie ich das rausbekommen sollte ;) ).

user profile iconretnyg hat folgendes geschrieben:
- die methode, die ordner nicht separat zu scannen bringt nur was bei *.*
- deine unit unterstützt *.* scheinbar nicht :shock: cntFoundfiles = 0
- deine unit unterstützt keine suche nach dateien wie "*bl*.mp3", "slayer", usw

Mhm, da muss ich mal gucken, denn bei mir hat sie funktioniert (muss ich jetzt mal gucken obs immer noch funktioniert ;) ). Aber Danke für den Tipp, werde mal gucken wo es happert.

user profile iconretnyg hat folgendes geschrieben:
- deine unit liefert keine verzeichnisnamen (wie bei luckie)

Wie meinst du das? Das er dir nur Ordner zurückgibt? Das habe ich für die Unit eigentlich nicht gedacht, da ich es für das Projekt nicht brauche, da aber der Filter der in der v2.0 drin ist auch nicht mehr für das ürsprüngliche gemacht ist, kann ich es ja noch einbauen ;).

user profile iconretnyg hat folgendes geschrieben:
- deine unit hat wie luckie's keine möglichkeit, einen fortschritt anzuzeigen

Das ist auch etwas was ich bisher nicht groß benötigt habe, da der Schwerpunkt bei der Fortschrittsanzeige beim MP3-Tag-Editor eigentlich auf das auslesen liegt. Für das normale Suchen habe ich einfach einen durchlaufenden Balken genommen, da die Berechnung für den kurzen Moment ein bisschen auswändiger wäre. Aber ich hatte mir darüber schon einmal Gedanken gemacht. Vlt. baue ich die Idee ja mal ein. ;)

user profile iconretnyg hat folgendes geschrieben:
- dafür kann man mehrere "suchbegriffe" übergeben, und die geschwindigkeit ist ziemlich gut, wenn ein resultat kommt...
Das mit den Resultaten muss ich mal wie gesagt überprüfen, da ich jedoch für mich die v1.0 reicht, ist es mir vlt. nicht aufgefallen das in der v2 ein Fehler sich mal wieder eingeschlichen hat. Aber das mit der Suchgeschwindigkeit war ja mein eigentliches Ziel, denn wie gesagt bei einer Suche 7 Formaten würde ich bei Luckies ein ganzes Stück Geschwindigkeitsverlust haben.


Heiko - So 23.10.05 10:57

So Bug behoben. Er trat auf, wenn als letztes Zeichen des Filters ein Sternchen war. Ich hatte einfach vergessen die Klammern zu setzten ;):

Delphi-Quelltext
1:
if not ((PosInStr=LenFileName) or Star) then Result:=false;                    


retnyg - So 23.10.05 16:35

user profile iconretnyg hat folgendes geschrieben:

- dafür kann man mehrere "suchbegriffe" übergeben, und die geschwindigkeit ist ziemlich gut, wenn ein resultat kommt...

wollte das gerade mal testen mit mehreren suchbegriffen, *.mp3 und *.m3u
deine unit sucht aber nur nach *.mp3
das feature tut also auch nicht ^^
ich habe irgendwie das gefühl, dass du deine eigene unit nicht gerade ausgiebig getestet hast ^^
ausserdem ist die parameterübergabe (mask) in dem array ziemlich unkomfortabel. wie wäre es mit '*.mp3;*.m3u' (die neue version meiner unit machts so) ?

//edit: ausserdem ist die verwaltung der rückgabewerte als globale variable äusserst ungünstig, und disqualifiziert die unit auf anhieb für multithreading


Heiko - So 23.10.05 17:40

Mhm, du scheinst immer irgendwelche Fälle zu haben, die ich nicht teste ;).

@Suchbegriffsübergabe: Könnte man umgestalten, allerdings würde ich dann das | nehmen ;).

@globale Variable für die Rückgabe: Warum disqualifiziert die sich dann dort gleich? Man braucht ja nur den Wert immer in eine andere Variable speichern, wodurch dann paralleles Suchen und auswerten der einzelnen Ergebnisse möglich wäre. Das gleiche würde man ja machen, wenn man parallel Suchen und Auswerten will, wenn man das Array als Parameter übergibt ;).

@Testen: Wie gesagt ich nutzte eigentlich nur v1.0, da ich nur die Endungen brauche, und da gibt es keine Probleme mit Mehrfachfilterung. Es kann eigentlihc nur daran leigen, das ich wahrscheinlich den Filter nur einmal rüberjage anstatt mehrmals ;).


Heiko - So 23.10.05 18:07

So, ich habe erstmal den Bug behoben. Der lag nicht daran das der Filter nicht ein 2.x durchlaufen wurde, sondern daran, das ich vergessen habe eine Variable für jeden durchlauf zurückzusetzten. Sprich wenn beim ersten Durchlauf false herauskam, kam nirgendwo mehr eine Stellen, die die Variable für den nächsten Filter wieder auf true setzte.


retnyg - So 23.10.05 18:20

user profile iconHeiko hat folgendes geschrieben:
Mhm, du scheinst immer irgendwelche Fälle zu haben, die ich nicht teste ;).

:shock: eigentlich ziemlich naheliegend :eyecrazy:
user profile iconHeiko hat folgendes geschrieben:
@Suchbegriffsübergabe: Könnte man umgestalten, allerdings würde ich dann das | nehmen ;).
damit brichst du aber mit der syntax, die windows-weit von suchprogrammen verwendet wird :?

user profile iconHeiko hat folgendes geschrieben:
@globale Variable für die Rückgabe: Warum disqualifiziert die sich dann dort gleich? Man braucht ja nur den Wert immer in eine andere Variable speichern, wodurch dann paralleles Suchen und auswerten der einzelnen Ergebnisse möglich wäre. Das gleiche würde man ja machen, wenn man parallel Suchen und Auswerten will, wenn man das Array als Parameter übergibt ;).

falsch: bei meiner variante kann ich 2 versch. threads mit 2 versch. variablen laufen lassen, ohne dass die sich gegenseitig im speicher rumpfuschen

user profile iconHeiko hat folgendes geschrieben:
@Testen: Wie gesagt ich nutzte eigentlich nur v1.0, da ich nur die Endungen brauche, und da gibt es keine Probleme mit Mehrfachfilterung. Es kann eigentlihc nur daran leigen, das ich wahrscheinlich den Filter nur einmal rüberjage anstatt mehrmals ;).

tja, wenn du hier eine unit reinstellst solltest du sie schon testen, auch wenn du sie selber nicht verwendest.
sonst könntest du gleich folgende prozedur hier anbieten:

Delphi-Quelltext
1:
2:
3:
4:
procedure findFiles(root, mask: string);
asm 
  nop
end;

das resultat ist (oder war) in einigen fällen gleich wie bei dir, aber um einiges schneller :lol:


Heiko - So 23.10.05 18:32

user profile iconretnyg hat folgendes geschrieben:
user profile iconHeiko hat folgendes geschrieben:
Mhm, du scheinst immer irgendwelche Fälle zu haben, die ich nicht teste ;).

:shock: eigentlich ziemlich naheliegend :eyecrazy:
user profile iconHeiko hat folgendes geschrieben:
@Suchbegriffsübergabe: Könnte man umgestalten, allerdings würde ich dann das | nehmen ;).
damit brichst du aber mit der syntax, die windows-weit von suchprogrammen verwendet wird :?

Mhm, denn kenne ich nicht, den mir ist noch kein solches Verfahren aufgefallen wo es so ist. Ich wollte den Filter so aufbauen wie bei einem OpenDialog etc. Aber wenn du sagst das es Standard ist werde ich mich dem Standard anschließen ;).

user profile iconretnyg hat folgendes geschrieben:
user profile iconHeiko hat folgendes geschrieben:
@globale Variable für die Rückgabe: Warum disqualifiziert die sich dann dort gleich? Man braucht ja nur den Wert immer in eine andere Variable speichern, wodurch dann paralleles Suchen und auswerten der einzelnen Ergebnisse möglich wäre. Das gleiche würde man ja machen, wenn man parallel Suchen und Auswerten will, wenn man das Array als Parameter übergibt ;).

falsch: bei meiner variante kann ich 2 versch. threads mit 2 versch. variablen laufen lassen, ohne dass die sich gegenseitig im speicher rumpfuschen
Jetzt ist mir klar was du meinst ;). Wobei eine parallele Suche sowieso nix bringt, da eine Festplatte ja davon nicht schneller wird und nur der Lesekopf der Festplatte dauernd sich hin und her bewegen muss, wodurch die lesegeschwindigkeit sich verringert ;). Außerdem braucht man das ja eigentlich nicht durch den Mehrfachfilter ;).

user profile iconretnyg hat folgendes geschrieben:
user profile iconHeiko hat folgendes geschrieben:
@Testen: Wie gesagt ich nutzte eigentlich nur v1.0, da ich nur die Endungen brauche, und da gibt es keine Probleme mit Mehrfachfilterung. Es kann eigentlihc nur daran leigen, das ich wahrscheinlich den Filter nur einmal rüberjage anstatt mehrmals ;).

tja, wenn du hier eine unit reinstellst solltest du sie schon testen, auch wenn du sie selber nicht verwendest.

Mhm, ich teste die schon, aber nicht mit allen Möglichkeiten die es gibt ;) Ich habe die Unit immer nur mit einem Filter getestet, da ich immer gleich die Performance mit der driveTools verglichen habe und ich da weiß, das die DT bei Suche mehrerer Dateien langsamer ist ;).

user profile iconretnyg hat folgendes geschrieben:
sonst könntest du gleich folgende prozedur hier anbieten:

Delphi-Quelltext
1:
2:
3:
4:
procedure findFiles(root, mask: string);
asm 
  nop
end;

as resultat ist (oder war) in einigen fällen gleich wie bei dir, aber um einiges schneller :lol:

Stimmt, die Variante wäre schneller ;).


Hast du jetzt eigentlich mal die Performance zwischen deiner und meiner jetzt funktionierenden Verglichen?


retnyg - So 23.10.05 20:30

user profile iconHeiko hat folgendes geschrieben:

Mhm, denn kenne ich nicht, den mir ist noch kein solches Verfahren aufgefallen wo es so ist. Ich wollte den Filter so aufbauen wie bei einem OpenDialog etc. Aber wenn du sagst das es Standard ist werde ich mich dem Standard anschließen ;).

musst nur mal im explorer nach *.jpg; *.jpeg; *.gif suchen
oder in deinem mailprogramm nach hallo; heiko
user profile iconHeiko hat folgendes geschrieben:
Jetzt ist mir klar was du meinst ;). Wobei eine parallele Suche sowieso nix bringt, da eine Festplatte ja davon nicht schneller wird und nur der Lesekopf der Festplatte dauernd sich hin und her bewegen muss, wodurch die lesegeschwindigkeit sich verringert ;). Außerdem braucht man das ja eigentlich nicht durch den Mehrfachfilter ;).

ed gibt auch leute, die besitzen mehr als eine festplatte

user profile iconHeiko hat folgendes geschrieben:
Hast du jetzt eigentlich mal die Performance zwischen deiner und meiner jetzt funktionierenden Verglichen?

das überlasse ich dir und dem publikum: siehe anhang
da drin ist meine unit, ein testprogramm, sowie deine und luckies unit


Delete - So 23.10.05 20:57

user profile iconretnyg hat folgendes geschrieben:

da drin ist meine unit, ein testprogramm, sowie deine und luckies unit

Das ist ja immer noch die alte. Ich habe doch schon daraufhingewiesen, dass es eine neue gibt.

Und mach mal die ganzen Warnungen und Hinweise aus dem Quellcode raus, das sieht ja schrecklich aus.


Heiko - Mo 24.10.05 07:55

So, ich habe mal in meinem Vergleichsprojekt die retFileSearch (die in dem einen Anhang dabei war) und die mpuDriveTools von Luckies Seite eingebaut:


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:
62:
63:
64:
65:
66:
67:
68:
69:
70:
unit Unit1;

interface

uses
  Windows, SysUtils, Forms, Dialogs, StdCtrls, Classes, Controls;

type
  TForm1 = class(TForm)
    Button4: TButton;
    procedure Button4Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation
  uses mpuDriveTools, SearchTool, retFileSearch;
{$R *.dfm}

procedure TForm1.Button4Click(Sender: TObject);
var
  i: Integer;
  Zeit1, Zeit2, Zeit3, StartZeit: Cardinal;
  ST: TStringArray;
  FS: TArray;
  FindFiles: TFindFiles;
  Found: Integer;
begin
  SetLength(ST, 1);
  ST[0]:='*.MP3';
  FindFiles:=TFindFiles.Create(Form1.Handle, 'C:\''*.MP3', true, false);
  for i:=0 to 1 do
  begin
    SearchTool.SearchFiles('C:\', ST, true);
    FindFiles.Init;
    FindFiles.FindFiles;
    Found:=retfilesearch.FindAllFiles('C:\''*.MP3', FS, nil, true, false, true);
  end;
  Zeit1:=0;
  Zeit2:=0;
  Zeit3:=0;
  for i:=0 to 1 do
  begin
    StartZeit:=GetCurrentTime;
    SearchTool.SearchFiles('C:\', ST, true);
    inc(Zeit1, GetCurrentTime-StartZeit);

    StartZeit:=GetCurrentTime;
    FindFiles.Init;
    FindFiles.FindFiles;
    inc(Zeit2, GetCurrentTime-StartZeit);

    StartZeit:=GetCurrentTime;
    Found:=retfilesearch.FindAllFiles('C:\''*.MP3', FS, nil, true, false, true);
    inc(Zeit3, GetCurrentTime-StartZeit);
  end;
  ShowMessage('ST: '+IntToStr(Zeit1 div 2)+' ms'+#13+
              'gefundene Dateien: '+IntToStr(SearchTool.cntFoundFiles)+#13+
              'DT: '+IntToStr(Zeit2 div 2)+' ms'+#13+
              'gefundene Dateien: '+IntToStr(FindFiles.InstanceSize)+#13+
              'FS: '+IntToStr(Zeit3 div 2)+' ms'+#13+
              'gefundene Dateien: '+IntToStr(Found));
end;

end.


Ergebnis:
- SearchTool(v2.0.3): 4164 ms
- DriveTools(v3.0): 7437 ms
- retFileSearch (v4): 6695 ms

Zum Ergebnis muss ich allerdings ein noch sagen. Bei Luckie werden die gefundenen Pfade nicht eingespeichert (oder ich habe nix gefunden wo es gemacht wird), dadurch entfällt ja die Zugriffs- und Schreibezeit auf dem RAM. Des weiteren ließ sich bei Luckie nicht überprüfen, ob er genauso wiel Dateien gefunden hat, da wie gesagt er nirgendswo etwas zusätzlich einspeichert ;).

Allerdings kam die Units nicht ganz vergleichen, denn jede Unit bietet mehr oder weniger zusätzliche Schnittstellen, die die Performance evtl. verlangsamen. Aber vom reinen Suchen dürfte es auf jeden Fall zu sehen sein, welche Unit die Nase vorne hat ;) :D .


Delete - Mo 24.10.05 12:44

user profile iconHeiko hat folgendes geschrieben:
Bei Luckie werden die gefundenen Pfade nicht eingespeichert (oder ich habe nix gefunden wo es gemacht wird)

Das wird dir doch alles per Nachricht zu geschickt.


retnyg - Mo 24.10.05 17:07

user profile iconHeiko hat folgendes geschrieben:

Ergebnis:
- SearchTool(v2.0.3): 4164 ms
- DriveTools(v3.0): 7437 ms
- retFileSearch (v4): 6695 ms

deine unit ist in der tat die schnellste, nachdem die dateisuche von windows gecached wurde.
die resultate von dir sind gecachte messzeiten.
mach mal deinen speicher voll (z.b. n delphi-prog das mit getmem viel speicher alloziert), so dass der wert "zugesichter speicher" im taskmanager grösser als der wert deines physikalischen arbeitsspeicher ist.
so werden die suchen nicht gecached, und du siehst welche strategie beim reinen festplattenhandling die nase vorn hat.
bei meinen messungen waren hier alle 3 units gleichschnell (abweichungen/schwankungen bis zu 3-4%), allerdings bei unterschiedlichem funktionsumfang.


retnyg - Mo 24.10.05 18:55

user profile iconretnyg hat folgendes geschrieben:
deine unit ist in der tat die schnellste, nachdem die dateisuche von windows gecached wurde.

nein, das stimmt so nicht: deine unit nur die schnellste, wenn man nur nach einem dateityp sucht.
sucht man nach *.* oder *.mp3;*.m3u ist meine schneller. wenn man bei meiner unit nach *.mp3;*.mp3 sucht ist sie doppelt so schnell als nur bei *.mp3 :lol:
das werde ich noch optimieren.


Heiko - Mo 24.10.05 19:18

user profile iconLuckie hat folgendes geschrieben:
user profile iconHeiko hat folgendes geschrieben:
Bei Luckie werden die gefundenen Pfade nicht eingespeichert (oder ich habe nix gefunden wo es gemacht wird)

Das wird dir doch alles per Nachricht zu geschickt.


Jupp weiß ich, des wegen findet man ja auch nix, wo etwas eingespeichert wurde ;). Da ich aber nicht noch was zusätzlich einbauen wollte, wo evtl. Performance verloren geht, konnte ich keine Verhgleiche ziehen, ob er wirklich alles gefuden hat ;).

user profile iconretnyg hat folgendes geschrieben:
user profile iconretnyg hat folgendes geschrieben:
deine unit ist in der tat die schnellste, nachdem die dateisuche von windows gecached wurde.

nein, das stimmt so nicht: deine unit nur die schnellste, wenn man nur nach einem dateityp sucht.
sucht man nach *.* oder *.mp3;*.m3u ist meine schneller. wenn man bei meiner unit nach *.mp3;*.mp3 sucht ist sie doppelt so schnell als nur bei *.mp3 :lol:
das werde ich noch optimieren.


Gemerkt das du dir selber widersprochen hast? Erst machste eine Aussage, danch zitierst du dich selber und bahauptest das die Aussage falsch ist ;). Das er bei *.mp3;*.mp3 doppelt so lange braucht ist eine gute Idee noch zu verbessern ;).

@Cache: Eigentlich nutzt jede Unit von uns den Cache. Zu mindestens war es bei der DriveTools von Luckie das gleiche Symton und ich glaube nicht das er es entfernt hat, was ja Nachteilig wäre ;). Und ich so weit iczh gesehen habe beruhhst du auf dem gleichem Symtom. Von daher ... ;).


retnyg - Mo 24.10.05 19:39

user profile iconHeiko hat folgendes geschrieben:
Gemerkt das du dir selber widersprochen hast?

nein, ich habe nur was richtiggestellt.

also: aus dem cache heraus ist deine unit die schnellste, wenn man nur nach einem dateityp sucht.
bei allen anderen aufgaben ist meine unit schneller.
deswegen die berichtigung.
user profile iconHeiko hat folgendes geschrieben:
Das er bei *.mp3;*.mp3 doppelt so lange braucht ist eine gute Idee noch zu verbessern ;).
nein, es ist genau umgekehrt.
user profile iconHeiko hat folgendes geschrieben:
@Cache: Eigentlich nutzt jede Unit von uns den Cache. Zu mindestens war es bei der DriveTools von Luckie das gleiche Symton und ich glaube nicht das er es entfernt hat, was ja Nachteilig wäre ;). Und ich so weit iczh gesehen habe beruhhst du auf dem gleichem Symtom. Von daher ... ;).

ja, zum cache: wenn der code im alltag hergenommen wird, läuft der code zu 90% `NICHT aus dem cache.
wenn ich nach etwas suche, dann normalerweise nur 1x, und nicht 10mal um die zeit zu messen.

deshalb ist der wert, der für die praxis interessanter ist, der ungecachte.

wenn du die performance-krone für die dateisuche willst, musst du mehr testen als nur den einen bereich, wo dein code die nase vorn hat. sonst ist das wie bei intel, die ihre benchmarks für die eigenen cpu's optimieren :roll:


Heiko - Mo 24.10.05 19:55

user profile iconretnyg hat folgendes geschrieben:
user profile iconHeiko hat folgendes geschrieben:
Das er bei *.mp3;*.mp3 doppelt so lange braucht ist eine gute Idee noch zu verbessern ;).
nein, es ist genau umgekehrt.


Das ist wirklich komisch ;). Aber bei mir stimmt das nicht. Wenn man 2x den geleichen Filter verwendet kommt das "erhoffte" Ergebnis das sie langsamer ist, was auch der Fall ist bei meiner Unit.


retnyg - Mo 24.10.05 20:25

wenn du gerade am debuggen bist: deine aktuelle variante liefert bei *.* oder * zu wenig treffer


Heiko - Di 25.10.05 06:48

Mhm, wenn ich bei mir vergleiche wieviel Daten auf C sind und wieviel er findet stimmen die schon. Meine Unit findet 133.037 Dateien und wenn ich bei C Strg+A und dann Eigenschaftenm mache, findet er 132.921 Daten. Warum er mehr findet kann ich dir gerade nicht sagen, aber es kann kein Bug sein vom Filter, denn der würde maximal verusrachen, das zu wenige da sind. Evtl. macht er bei den Egenschaften Systemdaten nicht mit, während die Unit ein paar Typen vom System noch findet.
Aber wie kommste darauf das er zu wenig findet? Findet er bei dir etwa nicht alle (v2.0.3?)?


retnyg - Di 25.10.05 13:56

der explorer sagt auf E: liegen 176.000 dateien.
das selbe sagt auch meine unit.
deine neueste unit sagt es wären 171.000


Heiko - Di 25.10.05 16:31

Ich habs vermutet dass du mit der Windowssuche vergleichst. Das Ergebnis stimmt jedoch nicht ganz, denn die Windowssuche sucht auch in zip-Dateien nach Dateien, während meine zip-Archive nicht durchsucht. Des wegen dieser Unterschied ;). Würde mich aber mal interessieren, warum deiner die findet ;).


retnyg - Di 25.10.05 16:51

wer redet von suchen ? E: öffnen, STRG-A, ALT-ENTER


mimi - So 06.11.05 11:21

So eine unit habe ich schon lange gesucht, ich habe sie jetzt zwar noch nicht getestet aber kann ich denn beim suchen die unterverzeichnise ausschalten ?
also so das nur das hauptverzeichnis durchsucht wird und nicht die andren die es evtl. noch geben könnte.

So mal schauen welche unit ich nehme, warscheinlich die von
"retnyg"
evlt. teste ich auch mal alle ich habe ein verzeichnis mit über 3000 midi dateien *G* ich fände es auserdem nicht schlecht wenn eine datei gefunden wird ein ereignis ausgelöst wird. Das hat den vorteil das ich die gefunden dateien nicht erst umwandel muss.

aber dies sollte ein und ausgeschlatet werden können.


Heiko - So 06.11.05 11:33

user profile iconmimi hat folgendes geschrieben:
So eine unit habe ich schon lange gesucht, ich habe sie jetzt zwar noch nicht getestet aber kann ich denn beim suchen die unterverzeichnise ausschalten ?

Ob die Unterordner mit durchsucht werden sollen oder nicht, kannst du bei allen 3 Units angeben.

user profile iconmimi hat folgendes geschrieben:
evlt. teste ich auch mal alle ich habe ein verzeichnis mit über 3000 midi dateien *G*

Bei midi dürfte mein Filter keine Probleme haben. ICh habe den Bug schon gefunden, aber bisher keine Zeit gehabt den auszubessern, da ich beim BwInf teilnehme.

user profile iconmimi hat folgendes geschrieben:
ich fände es auserdem nicht schlecht wenn eine datei gefunden wird ein ereignis ausgelöst wird. Das hat den vorteil das ich die gefunden dateien nicht erst umwandel muss.

aber dies sollte ein und ausgeschlatet werden können.

Was meinst du mit umwandeln? Und das mit dem Ereignis kann momentan Luckies Unit, wenn ich dich richtig verstanden habe, was du haben willst ;).


retnyg - So 06.11.05 14:11

user profile iconmimi hat folgendes geschrieben:

evlt. teste ich auch mal alle ich habe ein verzeichnis mit über 3000 midi dateien *G* ich fände es auserdem nicht schlecht wenn eine datei gefunden wird ein ereignis ausgelöst
aber dies sollte ein und ausgeschlatet werden können.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure callback (x:integer;t:tarray);
begin
   form1.Memo1.Lines.add(t[x]);
   application.ProcessMessages;
end;

procedure TForm1.Button2Click(Sender: TObject);
var liste: retfilesearch.tarray;
begin
  retfilesearch.FindAllFiles('C:\winxp\','*.mid',liste,callback,true);
end;


ahja und wegen unterverzeichnisse ned durchsuchen: statt dem true hinter callback ein false


mimi - So 06.11.05 15:01

@Heiko
mit umwanden meine ich z.b.: meistens wird ja eine TStringList erwartet aber wenn dies nicht der fall währe so wie bei luckie dort habe ich gelesen wird ein TStringArray erwartet.

aber wenn lucki's such funktioen ereignis unterstützt werde ich das in zukunpft verwenden. ja oder evlt. doch die von retnyg....

ich habe mir dem umfang noch nicht angeschaut nur mal die geschwindigkeits vergleiche, aber dies ist doch auch nur relativ: Das kommt doch auch drauf an wie schnell die festplatten sind und wie sie ausgelastet sind...


koller1 - So 06.11.05 17:45

@retnyg


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure callback (x:integer;t:tarray);
begin
   form1.Memo1.Lines.add(t[x]);
   application.ProcessMessages;
end;

Wie schreibe ich die Funktion um, dass ich alles in einer Listbox anzeigen lassen kann?

MFG
koller1


Heiko - So 06.11.05 17:51

Einfach:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure callback (x:integer;t:tarray);
begin
   form1.ListBox1.Items.add(t[x]);
   application.ProcessMessages;
end;


;)


koller1 - So 06.11.05 18:07

danke! Manchmal ist man aber auch wie vernagelt :autsch: :wink:


Heiko - So 28.05.06 17:47

So, nach einer Ewigkeit habe ich mich mal wieder an die "DF-Version" von SearchTool gesetzt um diese zu überarbeiten (da ich meine abgespeckte Variante in einem anderem Programm auch überarbeiten musste, auf Grund von größere Bauarbeiten ;) ). Herausgekommen ist V 3.0 Alpha

Was gibt es neues?


Warum nur Alpha?


*Dateiendung = die letzten Zeichen der Länge des Filters werden verglichen (Also beim Filter "p3" findet er auch Dateien mit der endung *.mp3).

Falls ihr hier wieder Bugs findet, wäre es schön, wenn ihr es mir melden würdet.

PS: Da pro Beitrag nur 3 Anhänge erlaubt sind, ist der Demo-Source bei dem Beitrag angehängt (um die Demo zu kompilieren, braucht ihr die VirtualStringTree-Komponente)


Heiko - So 28.05.06 20:01

So, ich habe nen kleinen BugFix eingeschioben. Bei Copy & Paste hatte ich vergessen eine Variable in einer if-Anweisung mit zu ändern (innerhalb des Vergleiches macht er sonst alles richtig ;) ).


Heiko - Sa 08.07.06 20:21

So noch eine kleine Info zur aktuellen Alpha. Und zwar wird diese momentan nicht von 95/98 und ME unterstützt, mangels UniCode-API. Wenn ich Zeit habe, mache ich demnächst die nächste Alpha, wo das Problem behoben ist.


Heiko - Mo 28.08.06 07:24

Nach mehreren Experimenten und ein paar Hilfreiche ergänzungen ist es endlich so weit: es gibt eine Alpha 2 (ist noch keine Final, da der Filter noch keine Masken (mit "*" ) erlaubt ;) ).

Was hat sich seit der letzten Alpha geändert?



Solltet ihr irgendwelche Bugs oder Synchronisationsfehler (wenn ich eine Kleinigkeit vergessen habe zu Synchronisieren) finden, meldet sie mir bitte. Ich habe zwar eigentlich die Unit so ziemlich komplett durchgetestet, aber man übersieht doch einiges.


Ach so, noch ein Kommentar zur Demo: Sie basiert jetzt nicht mehr auf VirtualStringTree, damit auch alle User die Demo direkt ausprobieren können (D2006 Leute werden trotzdem ein Problem haben, da die Shell-Kompos nicht existieren ;) ). Folglich werden bei UniCode-Dateien als ???-Dateien ausgegeben, da ja die Delphi-Kompos kein UniCode-Support haben :( (die Unit gibt die Dateien aber als UniCode-Bezeichnungen zurück ;) ).


Heiko - Mo 28.08.06 19:12

Beim letzten Upload ist eine Kleinigkeit daneben gegangen (bei mir auf dem Rechner, aber ka wieso ;) ). Ich habe noch einen kleinen Bugfix reingenommen, wo XP meckert, aber 98 nicht (ob ein Laufwerk bereit ist oder nicht). Das hatte ich entfernt, da 98 nicht gemeckert hatte ;). Bleibt trotzdem bei der Bezeichnung Alpha 2 ;). Ich hoffe das jetzt keine Probleme mehr bei der Demo existieren, wenn ja bitte melden.


0xCC - So 21.01.07 18:15

hi, ich habe deine komponente hergenommen, da sie mit widestrings umgehen kann.
allerdings hatte sie einige bugs und war relativ umständlich zu bedienen, weswegen ich sie etwas umprogrammiert habe.
ich häng sie mal an, vielleicht willst du ja was übernehmen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
// Version 3.0.int3  Alpha2 (21.07.07) von int3 software (www.int3.at) //
//     - Filtereinstellungen verbessert                            //
//       (WINAPI-Aufruf von PathMatchSpecW )                       //
//     - Fehlerhafte Fileextension-Routine durch eigene ersetzt    //                                                                 
//     - prozedur Quicksearch hinzugefügt                          // 
//     - bug bei rekursiver ordnerstruktur,                        //
//       wenn FFindDirs = false, entfernt                          // 
//     - wenn Zielhandle null ist, werden keine Messages verschickt// 
//     - Resetdata setzt nun die Länge der Dir und File-Arrays auf //
//       null, bevor der pointer auf nil geändert wird             //
//       um speicherleaks zu vermeiden                             //


Heiko - So 21.01.07 18:44

Hallo,

ich gucks mir mal an, was du da alles geändert hast. Und guck mal, in wie fern die Änderungen was bringen ;). Besonders PathMatchSpecW werde ich mir mal unter die Lupe nehmen, in wie fern er von der Performance her ist :lupe: .

Aber den den nervigsten Bug hast du trotzdem nicht gefunden, den ich lokal behoben habe, aber noch nicht hochgeladen habe :mrgreen: . Und zwar warten die beim abbrechen mittels Breka ewig aufeinander, bedingt dadurch, dass ich im Thread und beim Abbrechen MsgWaitForMultipleObjects nehme, und die sich die Nachrichten gegenseitig wegnehmen. Bis ich aber die Final rausbringe, wirds ggf. noch ein bissl brauchen, da ich gucken möchte, ob es Vorteil bringt, wenn ich PeekMessage nehme, anstatt dauernd zu synchroniseren. Da hängt es davon ab, wie es von der Performane her ist.

Aber auf jeden Fall danke, dass du mich mal wieder an die Unit erinnert hast. Denn in meinem Projekt läuft die so, wie ich es will, wes wegen ich die schon wieder (fast) vergesseen habe ;).

//EDIT: Die Idee von QuickSearch ist auch mal wieder gut. Diese Variante ist leider von Version 2 auf 3 verloren gegangen ;).


0xCC - So 21.01.07 19:57

user profile iconHeiko hat folgendes geschrieben:

Aber den den nervigsten Bug hast du trotzdem nicht gefunden, den ich lokal behoben habe, aber noch nicht hochgeladen habe :mrgreen: . Und zwar warten die beim abbrechen mittels Breka ewig aufeinander, bedingt dadurch, dass ich im Thread

liegt wohl daran, dass ich immer ohne thread vorgegangen bin, da ich alles sequentiell durcharbeite ohne mich mit callbacks rumzuschlagen. der part scheint nun fehlerfrei zu funktionieren.
du könntest die unit noch insoweit verbessern, dass wenn KEIN THREAD benutzt wird, du auf die criticalsections und locks verzichtest, da diese die performance doch ein bischen beeinträchtigen.


Heiko - So 21.01.07 19:58

So, ich habs mir mal gerade anguckt.

user profile icon0xCC hat folgendes geschrieben:
- Filtereinstellungen verbessert (WINAPI-Aufruf von PathMatchSpecW )

Ist natürlich die einfachere Variante, die ich auch aus probieren werde. Ich stolpere noch darüber:
Zitat:
Searches a string using an Microsoft MS-DOS wild card match type.

Denn mit MS-DOS verbinde ich immer die Begrenzung auf 8 Zeichen je Ordner/Datei. Ich hoffe mal, dass es bei der UniCode-Variante nicht der Fall ist ;).

user profile icon0xCC hat folgendes geschrieben:
- Fehlerhafte Fileextension-Routine durch eigene ersetzt

Wo war die Fehlerhaft? Meine hat nur ein bisschen mehr zugelassen, als es für eine reine Fileextension der Fall wäre. Aber das ist ja nicht schlimm, sondenr hat sogar seine Vorteile. Wenn man z.B. nach "\Test.mp3" sucht, hat man den Fall, dass er alle Dateien raussucht, die Test.mp3 heißen (ohne \ wäre es *Test.mp3). Und Dateiendungen gingen damit auch, wie man in der Demo gesehen hat.
Und SearchTool soll schließlich nicht nur nach Dateiendungen suchen können, sondern genauso viel können, wie die Windows-Suchfunktion.

user profile icon0xCC hat folgendes geschrieben:
- bug bei rekursiver ordnerstruktur, wenn FFindDirs = false, entfernt

Da haste Recht. Komisch, dass es mir gar nicht aufgefallen ist. Liegt wahrscheinlich daran, dass ich in meinem Projekt eine gekürzte Variante von ST nehme, damit keine unnötigen ASM-Codes drin sind, bei denen das Ergebnis feststeht ;).
user profile icon0xCC hat folgendes geschrieben:
- wenn Zielhandle null ist, werden keine Messages verschickt

Auch da muss ich dir Recht geben. Bei mir war 0 = keine Nachricht versenden, da ungültiges Handle. Dass Windows das auf PostThreadMessage umbiegt kann man ja nicht ahnen (bei SendMEssage steht z.B. nüscht davon drin, wie er auf 0 reagiert).
user profile icon0xCC hat folgendes geschrieben:
- Resetdata setzt nun die Länge der Dir und File-Arrays auf null, bevor der pointer auf nil geändert wird um speicherleaks zu vermeiden.

Im Gegenteil. Die Variante mit nil ist sogar besser, denn da ruft DynArrayClear auf (siehe CPU-Fenster), während er bei SetLength(..., 0) den Umweg über DynArraySetLength geht.

Eine erste Final kommt vlt. in den nächsten Tagen. Optimieren kann ichs später immer noch ;).


0xCC - So 21.01.07 20:21

user profile iconHeiko hat folgendes geschrieben:

Zitat:
Searches a string using an Microsoft MS-DOS wild card match type.

Denn mit MS-DOS verbinde ich immer die Begrenzung auf 8 Zeichen je Ordner/Datei. Ich hoffe mal, dass es bei der UniCode-Variante nicht der Fall ist ;).

das heisst nur dass die standard wildcards verwendet werden, wie beim dir-befehl, z.b *.mp? * *.*.
ich glaube, pathmatchspecw unterstützt sogar das folgende von haus aus: '*.mp3;*.wav;*.ogg' - da fiele sogar deine filtereexts tabelle weg.

user profile iconHeiko hat folgendes geschrieben:
user profile icon0xCC hat folgendes geschrieben:
- Fehlerhafte Fileextension-Routine durch eigene ersetzt

Wo war die Fehlerhaft? Meine hat nur ein bisschen mehr zugelassen, als es für eine reine Fileextension der Fall wäre. Aber das ist ja nicht schlimm, sondenr hat sogar seine Vorteile. Wenn man z.B. nach "\Test.mp3" sucht, hat man den Fall, dass er alle Dateien raussucht, die Test.mp3 heißen (ohne \ wäre es *Test.mp3). Und Dateiendungen gingen damit auch, wie man in der Demo gesehen hat.
Und SearchTool soll schließlich nicht nur nach Dateiendungen suchen können, sondern genauso viel können, wie die Windows-Suchfunktion.

ähm also ganz genau kann ich mich nicht mehr erinnern, ich weiss aber noch dass die fileext. die der filter berechnet hat, bei mir komplett nicht stimmte, als ich mit dem debugger durchgesteppt bin.
und da deine filterfunktion nichtmal * oder *.* richtig erkannt hat, habe ich gleich die dafür vorgesehen windows-funktion verwendet.

user profile iconHeiko hat folgendes geschrieben:

user profile icon0xCC hat folgendes geschrieben:
- Resetdata setzt nun die Länge der Dir und File-Arrays auf null, bevor der pointer auf nil geändert wird um speicherleaks zu vermeiden.

Im Gegenteil. Die Variante mit nil ist sogar besser, denn da ruft DynArrayClear auf (siehe CPU-Fenster), während er bei SetLength(..., 0) den Umweg über DynArraySetLength geht.

aha ? kann sein, ich wollte mal auf nummer sicher gehen. jedenfalls ist bei der funktion die performance egal, da sie bei jeder suche ja nur einmal aufgerufen wird. dafür habe ich den aufruf von GetArbeitsplatzName wegoptimiert, so dass es nur einmal beim constructor einer variablen zugewiesen wird und nicht bei jeder suche.


Heiko - So 21.01.07 20:31

[quote="user profile icon0xCC"]
user profile iconHeiko hat folgendes geschrieben:
ich glaube, pathmatchspecw unterstützt sogar das folgende von haus aus: '*.mp3;*.wav;*.ogg' - da fiele sogar deine filtereexts tabelle weg.

Jupp, funzt so. Habs schon ausprobiert (bevor du hier das gepostet hast). Und da Delphi sich um die Thread-Sicherheit bei Stringskümmert, wird der Code ein Stück kürzer, da ich mich darum nimmer kümmern muss ;). Und ich glaube nicht, dass ich diese Prozedur noch einmal selber schreiben werde, denn PathMatchSpec wird ja hoffentlich schon von Windows optimierts ein ;).
Aber dazu fällt mir noch was ein. Und zwar funzt deine Unit, also was du da geändert hast, nur noch unter den neueren OSes, denn du setzt voraus, dass die bekannt sind. Korrekt müsste es so hier sein:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  function PathMatchSpecA(pszFile, pszSpec: PAnsiChar): Boolean; stdcall;
  function PathMatchSpecW(pszFile, pszSpec: PWideChar): Boolean; stdcall;

implementation

  function PathMatchSpecA(pszFile, pszSpec: PAnsiChar): Boolean; external 'shlwapi.dll';
  function PathMatchSpecW(pszFile, pszSpec: PWideChar): Boolean; external 'shlwapi.dll';


Denn wenn man gleich

Delphi-Quelltext
1:
function PathMatchSpecW(pszFile, pszSpec: PWideChar): Boolean; stdcallexternal 'shlwapi.dll';                    

macht, so wie du es hattest, versucht Windows die DLL gleich beim start zu laden. Und wenn das S die Funktion nicht hat, gibts es eben nen Error. Von daher den Umweg über die Zweiteilung ;).

user profile icon0xCC hat folgendes geschrieben:
und da deine filterfunktion nichtmal * oder *.* richtig erkannt hat, habe ich gleich die dafür vorgesehen windows-funktion verwendet.

Das unterstützte die Unit, in dem man einfach einen leeren Filter setzt ;).

user profile icon0xCC hat folgendes geschrieben:
dafür habe ich den aufruf von GetArbeitsplatzName wegoptimiert, so dass es nur einmal beim constructor einer variablen zugewiesen wird und nicht bei jeder suche.

Jain. Ja klar ist es schneller. Aber gehe mal von einem Programm aus, dass 2h läuft. Bein Programmstart heißt der Arbeitsplatz noch "Arbeitplatz". Dann funzt es auch. Aber was ist wenn der Nutzter zwischendurch den Arbeitsplatz einfach mal umbennt zu "Mein PC". Dann würde die Optimierung eine Fehlermeldung verursachen, die ich nicht heraufbeschwöre. Von daher ist die Abfrage jedesmal erforderlich, außer man findet eine Möglichkeit diese Umbennung über Hooks oder so mitzubekommen. Dann wäre allerdings die Frage, ob Performancetechnisch vlt. nicht doch langsamer ist, da es ggf. keinen Extra-Hook dafür gibt, so dass man alle Änderungen am Dateisystem überwachen muss. Von daher lasse ich es so ;).

//EDIT: Einen Beitrag von dir übersehen

user profile icon0xCC hat folgendes geschrieben:
du könntest die unit noch insoweit verbessern, dass wenn KEIN THREAD benutzt wird, du auf die criticalsections und locks verzichtest, da diese die performance doch ein bischen beeinträchtigen.

Looks verwende ich ja nur, wenn irgendeine Property geändert wird. Von daher spielt es da keine Rolle, denn man ändert ja nicht aller 5ms die Configs ;). Ansonsten wäre eine Zusätzliche if-Abfrage erforderlich, die auch nicht gerade gut für die Performance ist ;).


0xCC - So 21.01.07 20:43

wenn das OS die funktion nicht hat läuft das programm eh nicht - ob dann die fehlermeldung früher oder später kommt ist sicher wurst.

dass ein leerer filter gleich '*.*' ist, kann man auch nicht riechen.

und von leuten, die ihren arbeitsplatz umbenennen, hab ich auch noch nie gehört.

so long


Heiko - So 21.01.07 20:50

user profile icon0xCC hat folgendes geschrieben:
wenn das OS die funktion nicht hat läuft das programm eh nicht - ob dann die fehlermeldung früher oder später kommt ist sicher wurst.

Nein. Ich Unterscheide zwischen UniCodefähigen-OSes und welchen, die es nicht sind. (Ansonsten wäre der Code nur halb so lang). Und nur durch solche Unterschieudngen ist es möglich, dass meine Unit unter allen OSes ab 95 laufen ;). Ich bekomme dann also keine Fehlermeldung.

user profile icon0xCC hat folgendes geschrieben:
dass ein leerer filter gleich '*.*' ist, kann man auch nicht riechen.

Spätestens bei der Code-Überarbeitung hätte es dir auffallen müssen ;).

user profile icon0xCC hat folgendes geschrieben:
und von leuten, die ihren arbeitsplatz umbenennen, hab ich auch noch nie gehört.

Ich auch nicht. Aber da es möglich ist... .Und shcließlich wirds nur einmal am Anfang der Suche aufgerufen, von daher spielt das noch keine große Rolle. Es spielt eigentlich nur das was sich in der Rekusion befindet eine Rolle.


Du weißt doch:
Zitat:
Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind.


Niko S. - Mo 22.01.07 18:35

Schade Hatte gehofft , das die Pas datei schneler sucht als Windows.
Dem is doch nicht so aber trozdem eien Schöne Komponente ;)
Auf jedenfall zu Gebrauchen.


Heiko - Mo 22.01.07 18:39

user profile iconSimak hat folgendes geschrieben:
Schade Hatte gehofft , das die Pas datei schneler sucht als Windows.


Ich habs heute früh mal getestet. Ein bissl schneller ist Windows im Vergleich (335ms vs. 310ms). Das würde ich vlt. erreichen, wenn ich is auf ASM-Ebene runter optimiere. Aber den Stress tue ich mir erst einmal nicht an ;). Aber war ja bald zu vermuten, denn MS sucht alle möglichen Dinge zum optimieren raus ;). Allerdings hängt die Suchgeschwindigkeit eher von der GUI-Geschwindigkeit ab...

//EDIT: An einer Stelle ein leerzeichen vergessen, so dass der Sinn verzerrt war ;).


Niko S. - Mo 22.01.07 20:38

Hu? dann hab ich wohl was falsch geamcht
Dein Suchtool: ~330sec
Windows Scuhe: ~70sec

Warum is bei dir son kliner unterschied und bei mir sno großer und dabei hat windoof sucher noch mehr mp3s gefunden o.O


Heiko - Mo 22.01.07 20:46

Hatte ich ja gesagt. Nur durch einen "kleinen" Tippfehler, klang es vlt. bissl anders. Habs jetzt so geändert,d ass man es ordentlich erkennt, was ich meine ;)

@Geschwindigkeit: Um die Suchgeschwindigkeit von Programmen vergleichen zu können, muss man vorher einen Suchlauf starten, der nicht in die Zeitmessung eingeht. Oder du startsest zwischen des Tests den Rechern neu, wobei beide Tests mit frisch gestartetem Betriebssystem sein sollte, um Gleichheit hervorzurufen. Kannst ja den Test nocheinmal machen. Bei mir war Windows eigentlich nie schneller (hast du mal die Demo von mir genommen? Denn die Standard-VCL ist arschlangsam ;). Und vergiss nicht: mkPostMessages oder mkNoneMEssage einzustellen (der Gerechtigkeit halber eher PosTmessage). Sonst bremst die VCL ;) )

@Mehr Suchresultate: Liegt daran, dass Windows auch noch Archive durchsucht, was ich nicht mache ;).


0xCC - Di 13.02.07 02:30

so...tut sich schon was in punkto bugfixes & verbesserungen, oder liegt das searchtool wieder ad acta ?


Heiko - Di 13.02.07 07:43

user profile icon0xCC hat folgendes geschrieben:
so...tut sich schon was in punkto bugfixes & verbesserungen, oder liegt das searchtool wieder ad acta ?

Tut sich schon. Das war für heute nach der Schule pelant (hab die Demo wieder auf VST geändert, da TD sowieso die Shellkompos nicht hat und ich ein Ersatz dafür brauchte). Ich war jetzt nur eine Woche nicht da (Ferien) und hab noch eine Änderung an meinem AbiForum durchgeführt, wes wegen ich nicht zum Test auf Win98 kam. Es könnte also sein, dass ichs heute schaffe. Bis zum Ende der Woche sollte ich es aber spätestens schaffen.


Heiko - Mi 28.02.07 20:13

So ich hab mal die neue Version hochgeladen (Änderungen etc. siehe erste Seite).
@0xCC: Hättest mich ruhig noch einmal erinnern können, denn am 17. oder so war die Unit fertig getestet etc. (hatte es nur vergessen hier hochzuladen, da ich da an meinem altem Rechner war) ;).

Im Prinzip hat es wirklich an der Demo gelegen, dass es so lange brauchte. Denn dadurch das ich nicht mehr D2005 nehme, sondern jetzt nur noch ausschließlich TD, musste ich die Demo umschreiben, da die ShellKompos bei TD nicht dabei sind. Von daher verwendet die Demo jetzt wieder VirtualStringTree, da der Explorer, den ich dort habe, auch darauf basiert (bei der neuen Explorerkomponente hatte ich das Problem, den Begriff "Arbeitsplatz" mir zurückgeben zu lassen, was ich aber auch demonstrieren wollte).

Was mich noch interessieren würde ist, wie meine Unit mit HArdlinks umgeht. Denn solche habe ich bei mir nicht auf der Platte zum testen ;).


moddin - Fr 13.04.07 21:37

also ich bleibe bei einer simplen recursiven dateisuche - das tool ist mir viel zu groß ;-)


Heiko - Fr 13.04.07 21:59

user profile iconmoddin hat folgendes geschrieben:
also ich bleibe bei einer simplen recursiven dateisuche - das tool ist mir viel zu groß ;-)


Zu groß ist gut. Die Threads blähen das soweit auf (durch die ganzen Getter und Setter). Ansonsten geht es nicht wesentlich kürzer, wenn du UniCode-Unterstützung besitzen willst, denn für Win98 und XP muss man eine Unterscheidung machen.

Letzt endlich ist deine Entscheidung, auch wenn dir einiges dabie an Komfort entgeht ;). Zum einem hängt in der Zeit des Suchens die GUI nicht, vor allem funktionieren dadurch die allgemeinen GUI Sachen noch, wie neuzeichnen und vergrößern, minimieren etc., und zum anderem brauchst du dich um nichts groß kümmern. Threads, vollständige Win-Kompatibilität und all so ein Zeug bekommst du schon geliefert.

Und groß ist es nun wirklich nicht. Vlt. scheinbar Zeilenaufwändig, aber ansionsten ist es nicht groß. Eigentlich wollte ich noch ein paar Filter einbauen, aber da muss ich erst gucken, denn wenn ich MSDN richtig verstanden habe, sind die Zeitstempel vom OS (oder war es Dateisystem?) abhängig, wie die formatiert zurückkommen. also potential zum Ausbauen gibt es noch genug :mrgreen: .


alias5000 - Fr 13.04.07 23:05

hm, bietet sich dann nicht irgendwie sowas in einer Art Pluginsystem an (etwas einfacher vllcht)
Je nachdem, was für Ideen du noch hast ;)

Gruß
alias5000


Heiko - Sa 14.04.07 10:53

Pluginsystem wäre ein bissl übertrieben ;). Aber ich habe schon überlegt, für den Filter eine Schnittstelle zu schaffen, also das jeder einen eigenen Filter schreiben kann. Als Alternative bieten sich Compilierschalter an ;).


Heiko - Sa 23.06.07 15:38

So es gibt jetzte V3.0.1, nachdem mich Gausi vorhin auf eine Kleinigkeit aufmerksam gemacht hat.

Und zwar wollte Gausi eine Warteschlange aufbauen und hat dazu im STFinish-Ereignis eine neue Suche gestartet. Da aber SearchTool noch darauf gewartet hat, dass er aus STFinish zurückgehrt (SendMessage), führt das zu einem Deadlock, da ja die Suche erst gestartet wird, wenn die alte beendet wurde. Bei PostMessage (Systemnachricht) trat der Fall nicht auf. Allgemein dürften Deadlocks nur auftreten, wenn in einem SendMessage-Ereignis eine neue Suche gestartet wird.
Da dies ein Fall war den ich von Seitens ST verhindern kann, allerdings nur bei STFinish und nicht beim STStart, habe ich das jetzt behoben. Freigeben kann man im ST im STFinsih trotzdem nicht ;).

Version 3.0.1:


//EDIT: Dafür gibt es keine extra Demo, da die Demos vom Fehler nicht betroffen sind ;).


Nils:D - Mi 18.07.07 10:47

Mal was ganz anderes: kannst du deine Unit nicht systemunabhängiger machen bzw. eine Linuxversion dafür auch noch machen ? Ich könnte das zwar, aber bis ich mich eingearbeitet habe, bist du schon längst fertig ;).


Heiko - Do 26.07.07 19:21

Mhm, sieht schlecht aus. Ich habe kein Linux (entweder hat Linux ne Allergie gegen meinen Rechner oder mein Rechner gegen Linux :mrgreen: ). Von daher baue ich das nicht ein. Das ist aber nur ein Grund. Wenn ich das für Linux machen wöllte, müsste ich die Unit im Prinzip neu schreiben, da fast alles auf WinAPI basiert, und das bissl Klebemittel dazwischen ist vernachlässigbar ;).


Heiko - Di 23.10.07 20:19

Hallo,

seit ein paar Tagen spiele ich mit dem Gedanken mal eine Art Umfrage hier zu machen, was eure Erfahrungen mit der Unit sind und wo ihr Probleme etc. festgestellt habt. Die WAK betreffen natürlich auch die Demo, denn als Entwickler sieht man einige Dinge einfacher, als es sie für "Fremdlinge" sind. Von daher wäre ich echt erfreut, wenn ihr Vorschläge zur Verbesserung der Demo bzw. der Unit macht.

Des weiteren werde ich in den ersten Posts [http://delphi-forum.de/viewtopic.php?t=48936] eine Auflistung an Features, die ich für die zukünftigen Versionen geplant habe (sobald ich mal wieder Zeit habe, mache ich auch an der Unit wieder etwas ;) ).

Und noch eine Kleinigkeit: um andere Demos der Unit zu haben, habe ich mir überlegt, auch im ersten Beitrag einer Auflistung der Programme zu machen, die SearchTool nutzen - sprich damit man auch Demos hat, wo es in der Wirklichkeit angewendet wird (man findet dazu im DF meistens auch genug Gegenbeispiele, wo sie nicht verwendet wird :mrgreen: ). Falls ihr ein Projekt habt, wo ihr dien Unit nutzt und das Proggi bereits public gemacht habt, postet hier einfach mal ;).

PS: Ich bin mal echt gespannt, was die Unit nach V3.0 für ein Feedback bekommt ;).

Grüße
Heiko


Delete - Di 23.10.07 21:24

Ich versuche schon längere Zeit, irgendeine der Demos zum Laufen zu kriegen, aber der ganze sche*** mit den zusätzlichen Komponenten funktioniert bei mir nicht!!!!!
Ich habe Delphi 2007.
Installiert habe ich:

EasyListviewSetup.exe
MustangPeakCommonLib.exe
VirtualShellToolsSetup2.0.exe
VirtualTreeviewSetup.exe

WAS NUN ???


Heiko - Mi 24.10.07 14:47

Hallo hathor,

hast du schon mal probiert ob die Virtual TreeVies Demos funktionieren (selbstkompiliert)? Wenn nicht, kann ich dir da leider nicht helfen (ich glaube nicht, dass es an der fehlenden TNT-Unit fehlt, denn soweit ich gesehen habe funzt das auch ohne).
Früher waren die Demos ohne den extra Kompos, aber seit ich D10 nutze und nicht mehr D9, geht das leider nicht mehr (hab keinen Explorer).

Falls D11 wieder die Standardmäßigen ShellKompos dabei hat, findeste ne ältere Demo dazu hier [http://www.delphi-forum.de/viewtopic.php?p=363314#363314]

Grüße
Heiko


Regan - Mi 24.10.07 14:57

Kannst du nicht einfach eine Version schreiben, die keine Fremdkomponenten verwendet!?


Heiko - Mi 24.10.07 15:04

Wie bereits im letzten Post gesagt, gibt es für die Alpha eine Version ohne Fremdkompo (bis D9 waren die ShellTools ja noch dabei ;) ). Bei neueren Versionen habt ihr die Wahl zwischem dem Installieren der Kompos (was sich empfiehlt um nicht woanders wieder Performanceverluste zu haben) oder die Demo von der Alpha zu nehmen und dort die ShellKompo wegzunehmen und dafür einen Edit hinlegen, in dem man den Pfad angibt. Mehr ist das IMHO nit zu machen. Und ich glaub, die alpha ist voll komatibel zur 3.0.1.


Heiko - Fr 26.10.07 20:17

Hallo,

eine neue Version ist erhältlich. Sie enthält einen kleinen "Bugfix" (die eine CriticalSection war sinnlos).


Des weiteren findet ihr jetzte den Demo-Source im ersten Posts inkl. einer Demo, die nur die Standardkompos verwendet!

Grüße
Heiko