Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   FindFirstFileEx (https://www.delphipraxis.net/160678-findfirstfileex.html)

Schwedenbitter 25. Mai 2011 19:48

FindFirstFileEx
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich habe bereits hier und auch in einer Suchmaschine nach FindFirstFileEx gesucht. In Bezug auf Delphi aber nichts gefunden.

Ich möchte in einem zeitkritischen Programm gern ausschließlich nach Verzeichnissen suchen über die API. Ich habe in SysUtils bereits gesehen, dass einfach alles gelesen und erst danach gefiltert wird. Auch mit
Delphi-Quellcode:
FindFirstFile
, welches eben in
Delphi-Quellcode:
SysUtils.FindFirst
genutzt wird, kann man nicht im Vorfeld filtern. Die Nutzer werden insoweit nur "geblendet", als sich SysUtils um das Filtern kümmert <- aber nachträglich.
So bin ich auf MSDN-Library durchsuchenFindFirstFileEx gestoßen. Über die Parameter
Delphi-Quellcode:
fInfoLevelId
kann man mitteilen, dass man nur das nötigste wissen will und über
Delphi-Quellcode:
fSearchOp
soll man laut MSDN nur Directories zurück bekommen; allerdings steht dort auch, dass man keine Meldung bekommt, falls das Dateisystem dies nicht unterstützt. Schließlich soll man über
Delphi-Quellcode:
FIND_FIRST_EX_LARGE_FETCH
die Suche beschleunigen können.

Nun meine Fragen:
1. In
Delphi-Quellcode:
Windows.TFindexInfoLevels
sind nur 2 statt der 3 bei MSDN ausgewiesenen Werte deklariert.
Delphi-Quellcode:
FindExInfoBasic
fehlt dort, was am performantesten sein soll. Kann man das einfach so (nach)deklarieren? Falls ja, wie?
2. Unter
Delphi-Quellcode:
Windows.TFindexSearchOps
gibt es zwar
Delphi-Quellcode:
FindExSearchLimitToDirectories
. Das scheint aber wirkungslos zu sein. Es wird trotzdem jeder Eintrag inkl. Dateien angezeigt. Welche Dateisysteme außer NTFS gibt es denn noch? Unterstützt NTFS das nicht? Falls doch, wie bekommen ich heraus, ob die konkrete Partition mit NTFS es unterstützt?
3.
Delphi-Quellcode:
FIND_FIRST_EX_LARGE_FETCH
ist - zumindest in der Windows.pas - nicht deklariert. Laut MSDN hat es den Wert 2. Wenn ich das nachträglich deklariere, liefert mir
Delphi-Quellcode:
GetLastError
aber "Falscher Parameter". Wo liegt hier mein Denkfehler?

Den Quellcode habe ich beigefügt.

Gruß, Alex

P.S. Bitte nicht wundern! Ich habe alles selbst deklariert, weil in TurboDelphi z.B. der Rückgabewert für FindFirstFileEx fälschlich als Bool deklariert und noch mehr Fehler drin waren.

ASM 25. Mai 2011 22:12

AW: FindFirstFileEx
 
(zu 1) FindExInfoBasic: Zitat MSDN ="This value is not supported until Windows Server 2008 R2 and Windows 7."

(zu 2) FindExSearchLimitToDirectories: Zitat MSDN = "If directory filtering is desired, this flag can be used on all file systems, but because it is an advisory flag and only affects file systems that support it, the application must examine the file attribute data stored in the lpFindFileData parameter of the FindFirstFileEx function to determine whether the function has returned a handle to a directory."
MS schweigt sich darüber aus, welches Filesystem derzeit dieses Flag unterstützt; offensichtlich keines (MS 2005: "reserved for future use"). Nach übereinstimmenden Berichten jedenfalls "NTFS is not actually part of the operating systems supported".
Also selbst alles rausfiltern, was (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)=0 hat).

(zu 3) FIND_FIRST_EX_LARGE_FETCH: Zitat MSDN = "This value is not supported until Windows Server 2008 R2 and Windows 7."
Setze den Wert für dwAdditionalFlags einfach auf "0", dann sollte es funktionieren.

Schwedenbitter 26. Mai 2011 00:00

AW: FindFirstFileEx
 
Danke für die Erklärungen. Ich hatte zwar den Text bei MSDN gelesen; scheinbar zu oberflächlich. Ich hatte das nur kurz durchgesehen und mir war das fett gedruckte "Windows XP" ins Auge gefallen. Wieso drucken sie das erst fett, wenn dann im Schmaldruck das wirklich wichtige geschrieben steht?

Zumindest für
Delphi-Quellcode:
FindExSearchLimitToDirectories
steht dort aber Minimum supported "Windows 2000 ...". Also müsste doch das klappen. Und dennoch muss ich nachträglich filtern. Wie das?

Wenn ich das richtig deute, kann ich mir das also sparen, wenn mein Programm hauptsächlich auf Rechnern mit Windows XP eingesetzt werden soll.

Gruß, Alex

ConnorMcLeod 2. Jul 2011 13:38

AW: FindFirstFileEx
 
Nach allem, was ich so gelesen habe, kann man diesen Wert derzeit leider vergessen. Also alles selbst filtern, ist aber egal, weil irgendjemand sowieso filtern muss und die Performance daher immer von einem Filter belastet wird.

Meine Frage im Anschluss dazu:
Wenn ich in einem Verzeichnis nach '*.dpr' suche, dann werden zwei Dateien gefunden:
-) meinprojekt.dpr und
-) meinprojekt.dproj
Danach habe ich aber nicht gesucht. Die .dproj-Datei sollte nicht geliefert werden. Weiss jemand, wie man die korrekte Antwort erzwingen kann?

Uwe Raabe 2. Jul 2011 14:12

AW: FindFirstFileEx
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1109602)
Wenn ich in einem Verzeichnis nach '*.dpr' suche, dann werden zwei Dateien gefunden:
-) meinprojekt.dpr und
-) meinprojekt.dproj
Danach habe ich aber nicht gesucht. Die .dproj-Datei sollte nicht geliefert werden. Weiss jemand, wie man die korrekte Antwort erzwingen kann?

Das kommt daher, daß "meinprojekt.dproj" als kurzen Namen "MEINPR~1.DPR" oder sowas Ähnliches hat.

Wenn du FindFirstFileEx verwendest, kannst du FindExInfoBasic als fInfoLevelId übergeben. Funktioniert aber erst mit Windows 7 oder Windows Server 2008 R2.

ConnorMcLeod 2. Jul 2011 15:00

AW: FindFirstFileEx
 
Das dachte ich auch, als ich die Hilfe gelesen hatte, aber in windows.pas steht:
Delphi-Quellcode:
type
  _FINDEX_INFO_LEVELS = (FindExInfoStandard, FindExInfoMaxInfoLevel);
Bei beiden Werten kommt dasselbe Ergebnis.

Uwe Raabe 2. Jul 2011 15:35

AW: FindFirstFileEx
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1109624)
Das dachte ich auch, als ich die Hilfe gelesen hatte, aber in windows.pas steht:
Delphi-Quellcode:
type
  _FINDEX_INFO_LEVELS = (FindExInfoStandard, FindExInfoMaxInfoLevel);
Bei beiden Werten kommt dasselbe Ergebnis.

Immerhin, bei einem älteren OS sollte der zweite Wert gar nichts liefern. Aber das zeigt mal wieder, daß die Microsoft-Programmierer wohl die Dokumentation nicht gelesen haben...

himitsu 2. Jul 2011 20:03

AW: FindFirstFileEx
 
In neueren Windows (ich glaub ab Vista oder 7) wird standardmäßig erstmal kein Kurzname mehr erstellt (solange er nicht benötigt oder gezielt erstellt wurde) ... so hat man in Zukunft (vorallem wenn es mal keine ANSI-Programme mehr gibt) endlich Ruhe mit den Kurznahmen. :angle:

ConnorMcLeod 3. Jul 2011 04:57

AW: FindFirstFileEx
 
Für wen es interessiert ... ich habe es dzt so gelöst:

Delphi-Quellcode:
          lhFoundFile := THandle(
            Windows.FindFirstFileEx(
                PWideChar(inPath + lsFileMask)
              , lIndexInfoLevels
              , lfdStruct
              , lIndexSearchOps
              , nil
              , ldwAdditionalFlags
              )
            );
                   
          if (lhFoundFile <> INVALID_HANDLE_VALUE) then
          begin
            repeat
              lsFileNameOnly := ExtractFileName(string(lfdStruct.cFileName));
              if    (0 = (lfdStruct.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))
                 and CompareWildString(UpperCase(lsFileMask), UpperCase(lsFileNameOnly)) // <= das ist der Trick
              then
              begin
                // gefunden!
              end;
            until not Windows.FindNextFile(lhFoundFile, lfdStruct^);
          end;
          Windows.FindClose(lhFoundFile);
CompareWildString ist aus der CodeLib, himitsu's Variante war mir zuviel Aufwand hier.
Der Witz an FindFirstFileEx ist, dass es (scheinbar) x-fach schneller als FindFirst ist. Daher möchte ich es unbedingt verwenden. (Wobei der hier gefixte Fehler auch bei FindFirst auftritt).

Schwedenbitter 3. Jul 2011 09:59

AW: FindFirstFileEx
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1109721)
Für wen es interessiert ...
Der Witz an FindFirstFileEx ist, dass es (scheinbar) x-fach schneller als FindFirst ist. Daher möchte ich es unbedingt verwenden. (Wobei der hier gefixte Fehler auch bei FindFirst auftritt).

Das ist auch meine Erfahrung, weshalb ich damit rumexperimentiert hatte. Braucht es das
Delphi-Quellcode:
ExtractFileName
wirklich?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:39 Uhr.
Seite 1 von 2  1 2      

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