Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   GetFileSize - welches ist die bessere Funktion? (https://www.delphipraxis.net/194137-getfilesize-welches-ist-die-bessere-funktion.html)

Glados 20. Okt 2017 16:20

GetFileSize - welches ist die bessere Funktion?
 
Ich teste gerade ein paar bei der Suchmaschine meiner Wahl gefundenen GetFileSize-Funktionen aus und vergleiche sie.
Mir ist aufgefallen, dass die FindFirst-Funktion (die erste) langsamer ist als die zweite.

Habt ihr noch bessere / schnellere?

Hier meine Funde
Delphi-Quellcode:
 function GetFileSizeA(const aFileName: string): Int64;
 var
  SR: TSearchRec;
 begin
  Result := 0;

  if not FileExists(aFileName) then
   Exit;

  if FindFirst(aFileName, faAnyFile and not faDirectory, SR) = 0 then
   try
    Result := SR.Size;
   finally
    System.SysUtils.FindClose(SR)
   end;
 end;

 function GetFileSizeB(FileName: string): Int64;
 var
  Handle: Integer;
  iFileSize: Int64;
 begin
  iFileSize := 0;
  Handle := FileOpen(FileName, fmOpenRead);

  if Handle <> -1 then
   try
    iFileSize := iFileSize + FileSeek(Handle, Int64(0), 2);
   finally
    FileClose(Handle);
   end;

  Result := iFileSize;
 end;

 function GetFileSizeC(aFileName: string): Int64;
 var
  F: TSearchRec;
 begin
  if FindFirst(aFileName, faAnyFile, F) = 0 then
   try
    Int64Rec(Result).Hi := F.FindData.nFileSizeHigh;
    Int64Rec(Result).Lo := F.FindData.nFileSizeLow;
   finally
    System.SysUtils.FindClose(F);
   end;
 end;

Uwe Raabe 20. Okt 2017 16:34

AW: GetFileSize - welches ist die bessere Funktion?
 
GetFileSizeA macht vorher noch ein überflüssiges FileExists. Ist die immer noch langsamer wenn du das weglässt?

Hast du schon mal GetFileSize aus Winapi.Windows versucht?

Glados 20. Okt 2017 16:38

AW: GetFileSize - welches ist die bessere Funktion?
 
Wenn ich bei A das FileExists weglasse, ist es noch langsamer als B.

Wenn die Datei existiert, ist die Reihenfolge von schnell nach langsam: C, B, A

Wenn die Datei nicht existiert: B, C, A (hier ist B etwa doppelt so schnell wie A und B)

Uwe Raabe 20. Okt 2017 16:56

AW: GetFileSize - welches ist die bessere Funktion?
 
Wie misst du denn die Zeiten? Vielleicht spielt da der Windows-Filecache eine Rolle?

Glados 20. Okt 2017 19:20

AW: GetFileSize - welches ist die bessere Funktion?
 
Das mit dem FileCache ist nicht so wichtig.

Delphi-Quellcode:

var
 SW: TStopwatch;
 i, X: Integer;
 D1, D2, D3: Integer;

const
 FILE_: string = '\\?\D:\2017-06-12 16-54-48.mkv';
begin
 SW := TStopwatch.Create;
 SW.Start;
 for i := 0 to 9999 do
  X := GetFileSizeA(FILE_);
 SW.Stop;
 D1 := SW.ElapsedMilliseconds;

 SW := TStopwatch.Create;
 SW.Start;
 for i := 0 to 9999 do
  X := GetFileSizeB(FILE_);
 SW.Stop;
 D2 := SW.ElapsedMilliseconds;

 SW := TStopwatch.Create;
 SW.Start;
 for i := 0 to 9999 do
  X := GetFileSizeC(FILE_);
 SW.Stop;
 D3 := SW.ElapsedMilliseconds;

 Caption := X.ToString; // nur, damit X nicht wegoptimiert wird
 Caption := D1.ToString + ' - ' + D2.ToString + ' - ' + D3.ToString;

himitsu 21. Okt 2017 14:14

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Das mit dem FileCache ist nicht so wichtig.
Doch?

Wenn der erste aufruf 10 Sekunden dauert und die nachfolgenden 9999 nur 1 Millisekunde,
dann sieht es fast langsamer aus, als die andere Variante, wo alle Aufrufe 2 Millisekunden dauern.
Im realen Betrieb sieht es oftmals auch so aus, dass es den Cache nicht gibt und alles "neu" eingelesen wird.

Außerdem ist dieser Test nicht aussagefähig, denn es ist ein Unterschied, ob man von 10.000 Dateien einmal den Wert ausliest,
oder ob man es "sinnlos" 10.000 Mal bei der selben Datei im selben Verzeichnis macht.
Und noch sinnloser sind solche "Benchmarks", wenn am Ende noch andere Dinge gemacht werden und es da auf das Zusammenspiel drauf ankommt.

Ich kann noch so oft mein Tempo auf 100 Meter messen und das Ergebnis für gut befinden, aber beim Marathon bin ich dennoch voll am Arsch.


Und dann kann der eine Code gern 1% schneller sein, aber sein Code ist grauenhaft ... dann doch lieber der andere etwas Langsamere, der aber wenigstens viel schönder und fehlerunanfälliger ist. (außer es komt einmal, was extrem selten vorkommt, doch auf jede Nanosekunde drauf an)
Zusätzlich kommt es auch noch auf die Hardware drauf an, denn wenn das Programm beim Entwickler schnell ist, aber in den Zielumgebungen sich selber sinnlos ausbemst, dann bringt es garnichts.


Bestes Beispiel sind die schwachsinnigen Dateikopierdialoge vom Windows Explorer ... die könnten und waren früher mal wesentlich schneller, aber jetzt kannst du die Performance komplett vergessen. (beim Kopieren einzelner/weniger Dateien)

Glados 21. Okt 2017 14:15

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Doch?
Mir ist es aber recht egal.

Zitat:

Und noch sinnloser sind solche "Benchmarks", wenn am Ende noch andere Dinge gemacht werden
Wo werden denn andere Dinge gemacht?

Ist jetzt aber gut. Kannst aufhören auf mich einzuschlagen.

Luckie 21. Okt 2017 15:04

AW: GetFileSize - welches ist die bessere Funktion?
 
Wenn es dir egal ist, dass der FileCache mit reinspielt und du so keine vergleichbaren Ergebnisse bekommst, dann ist das ganze doch irgendwie sinnlos. :?

Glados 21. Okt 2017 15:21

AW: GetFileSize - welches ist die bessere Funktion?
 
Das mit dem Cache ist doch so:
wenn Windows nicht aus dem Cache ließt, dann wird das Ganze sicherlich sehr sehr viel länger dauern. Oder irre ich mich?
Das hier dauert bei mir nur rund 180ms. Ich kann mir nicht vorstellen, dass hier ohne Cache gearbeitet wird.

Uwe Raabe 21. Okt 2017 15:51

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Glados (Beitrag 1383847)
Das mit dem Cache ist doch so:
wenn Windows nicht aus dem Cache ließt, dann wird das Ganze sicherlich sehr sehr viel länger dauern. Oder irre ich mich?
Das hier dauert bei mir nur rund 180ms. Ich kann mir nicht vorstellen, dass hier ohne Cache gearbeitet wird.

Bis auf den ersten Zugriff ist das wohl auch so. Deswegen solltest du einen zusätzlichen Aufruf vor die erste Messung machen, damit der Nicht-Cache-Zugriff diese nicht verfälscht. Du kannst auch mal die Reihenfolge der Aufrufe vertauschen. Z.B. erst C, dann B dann A. Bekommst du dann dasselbe Ergebnis bezüglich der Performance?

jbg 22. Okt 2017 10:39

AW: GetFileSize - welches ist die bessere Funktion?
 
Ich werfe auch noch eine weitere Funktion in den Raum.
Delphi-Quellcode:
function GetFileSizeD(const FileName: string): Int64;
var
  FileInfo: TWin32FileAttributeData;
begin
  FillChar(FileInfo, SizeOf(FileInfo), 0);
  if GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @FileInfo) then
  begin
    Int64Rec(Result).Hi := FileInfo.nFileSizeHigh;
    Int64Rec(Result).Lo := FileInfo.nFileSizeLow;
  end
  else
    Result := 0; // -1 wäre ein besserer Wert, da es Dateien gibt die Größe 0 haben
end;

Glados 22. Okt 2017 12:19

AW: GetFileSize - welches ist die bessere Funktion?
 
Deine Funktion ist bisher mit Abstand die schnellste.
Sie ist circa fünfmal so schnell wie B.
Ist FindFirst denn wirklich SO langsam und GetFileAttributes(Ex) so viel schneller? Kommt mir schon fast komisch vor.

jbg 22. Okt 2017 12:59

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Glados (Beitrag 1383864)
Ist FindFirst denn wirklich SO langsam

FindFirstFile, das hinter FindFirst steckt, ist für das Abfragen der Informationen von mehreren Dateien ausgelegt. Wenn du nur eine Datei haben willst, dann ist der Overhead im Vergleich zum GetFileAttributes um einiges größer. Zudem steckt ein anderer System-Aufruf dahinter. Vor allem wenn man auf ein Netzlaufwerk zugreift, wird FindFirstFile so richtig langsam.

Zu FileOpen+FileClose: Virenscanner klinken sich hier sehr gerne ein, und können das ganze gravierend verlangsamen, vor allem beim Öffnen zum Schreiben wird FileClose sehr langsam. Aber auch beim Öffnen zum Lesen prüft der Virenscanner im FileOpen die Datei.

Glados 22. Okt 2017 13:26

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Vor allem wenn man auf ein Netzlaufwerk zugreift, wird FindFirstFile so richtig langsam.
Ja das habe ich schon oft bemerkt. Ich versuche mich da heute mal reinzufuchsen und spiele ein bisschen mit GetFileAttributes rum.
Vielleicht bekomm,t man damit ja sogar ein DirectoryExists hin.

jbg 22. Okt 2017 18:44

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Glados (Beitrag 1383869)
Vielleicht bekomm,t man damit ja sogar ein DirectoryExists hin.

Ja bekommt man. Im Flags Feld ist dann FILE_ATTRIBUTE_DIRECTORY gesetzt, vorausgesetzt es existiert. Man darf sich vom "File" in GetFileAttribute(Ex) nicht verwirren lassen.

Jasocul 23. Okt 2017 06:50

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Glados (Beitrag 1383847)
Das hier dauert bei mir nur rund 180ms.

Dann sind deine Prüfschleifen zu kurz.
Um Einflüsse durch das Betriebssystem zu minimieren, muss es ausreichend lange laufen.
Der Cache wurde als Problem schon genannt.
Aber auch jeder Task, Dienst, etc. nimmt Einfluss. Spätestens, wenn irgendein anderer Thread etwas mit der Festplatte macht, werden die Messungen nahezu sinnlos, wenn nur so kurze Zeiträume verwendet werden.
Ich nehme außerdem mal an, dass du keinen speziellen Rechner für die Tests verwendest. Das heißt, dass jeder neue Durchlauf andere Bedingungen hat. Wenn du zum Beispiel deine Test-Anwendung neu kompiliert hast, sind die Voraussetzungen verändert.

Wenn du also ernsthaft feststellen willst, welches die schnellste Variante ist, musst du erstmal die Testumgebung optimieren. Ansonsten sind deine Ergebnisse nicht wirklich aussagekräftig.

btw: Ich habe selbst eine kleine Anwendungen, die Dateien im mittleren 6-stelligen Bereich verarbeitet. Das Einlesen der Informationen dauert i.d.R. weniger als 3 Minuten, wobei die Visualisierung und Sortierung schon enthalten sind. Über eine großartige Optimierung habe ich mir nur wenige Gedanken gemacht, da es meistens ein automatisierter Prozess ist.
Daher stellt sich mir die Frage, wofür brauchst du denn eine derartige Optimierung?

Glados 23. Okt 2017 10:28

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Wenn du also ernsthaft feststellen willst, welches die schnellste Variante ist, musst du erstmal die Testumgebung optimieren
Ich behaupte einfach mal, dass das Umsetzen einer speziellen Testumgebung nicht notwendig ist, wenn ein dauerhafter Unterschied von >50% zu sehen ist.

Codehunter 23. Okt 2017 10:44

AW: GetFileSize - welches ist die bessere Funktion?
 
Aus der Praxis heraus würde ich sagen, es ist vom Aufwand her um Längen billiger, die Liste der Systemanforderungen um den Punkt SSD (ggf. sogar PCIe-SSD, M.2 usw.) zu ergänzen, als sich derart in Millisekunden zu versteigen. Allerdings gebe ich zu, es gibt Anwendungsfälle wo das absolut gerechtfertigt ist.

Zitat:

Zitat von himitsu (Beitrag 1383841)
Bestes Beispiel sind die schwachsinnigen Dateikopierdialoge vom Windows Explorer ... die könnten und waren früher mal wesentlich schneller, aber jetzt kannst du die Performance komplett vergessen. (beim Kopieren einzelner/weniger Dateien)

Boah da hab ich mich letztens auch drüber aufgeregt. Ich kopiere eine Programmverknüpfung im Classic-Shell-Startmenü. Also technisch gesehen eine .LNK, innen drin eine INI und insgesamt eine Handvoll Bytes. Da macht das grottige Windows 10 doch tatsächlich dieses Fenster auf und misst die Kopiergeschwindigkeit nebst Diagrammdarstellung. Allein die Berechnung dessen hat mehr Zeit gefressen als die reine Dateischubserei.

Jasocul 23. Okt 2017 10:55

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Glados (Beitrag 1383925)
Zitat:

Wenn du also ernsthaft feststellen willst, welches die schnellste Variante ist, musst du erstmal die Testumgebung optimieren
Ich behaupte einfach mal, dass das Umsetzen einer speziellen Testumgebung nicht notwendig ist, wenn ein dauerhafter Unterschied von >50% zu sehen ist.

Behaupten kann man viel.
Dann baue deinen Test doch mal so um, dass er statt 180 ms besser ca. 2 Minuten dauert. Das würde zumindest den Cache-Anteil bei der Bewertung stark verringern. Bleibt der Unterschied dann immer noch bei über 50%, würde ich auch von einer Signifikanz ausgehen.

Glados 23. Okt 2017 11:55

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Dann baue deinen Test doch mal so um, dass er statt 180 ms besser ca. 2 Minuten dauert.
Ich habe zwar keinen gebaut der 2 Minuten dauert, dafür aber mehr als ein paar Millisekunden.

GetFileSizeA: 26 Sekunden Laufzeit
GetFileSizeD: 2 Sekunden Laufzeit

Jasocul 23. Okt 2017 12:10

AW: GetFileSize - welches ist die bessere Funktion?
 
Das bestätigt dann ja deine Annahme.
OK, war eigentlich abzusehen, da ja FileExists, FindFirst und FindClose in der D-Variante gar nicht vorkommen. Aber dieser Performance-Test war ja noch einfach. Bei komplizierteren Sachen, die nicht so offensichtlich sind, muss man schon genauer testen. Und darum ging es mir an dieser Stelle.

Uwe Raabe 23. Okt 2017 12:25

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Jasocul (Beitrag 1383938)
Bei komplizierteren Sachen, die nicht so offensichtlich sind, muss man schon genauer testen. Und darum ging es mir an dieser Stelle.

Um strukturelle Fehler im Testaufbau zu finden, sollte man die verschiedenen Durchläufe zunächst immer mit derselben Implementierung laufen lassen (hier alle Messungen erst mit A, dann B usw.). Wenn dann immer die erste Messung signifikant schlechter ist als die folgenden (z.B. wegen des Cache), sollte man den Test solange verbessern bis das ausgeglichen ist.

Das ist so in etwa das Pendant zum Test-Driven Development, bei dem man einen Test bewusst fehlschlagen lässt, um erstmal den Test-Harness zu überprüfen.

Glados 23. Okt 2017 12:59

AW: GetFileSize - welches ist die bessere Funktion?
 
Alles erledigt was ihr vorgeschlagen habt.

Resultat:
A = 2 Minuten, 45 Sekunden
D = 31 Sekunden

Benmik 2. Apr 2024 15:23

AW: GetFileSize - welches ist die bessere Funktion?
 
Aus gegebenem Anlass habe ich mal gemessen, wie die Funktion GetFileInformationByHandle, mit der auch die Dateigröße bestimmt werden kann, sich schlägt. Hierbei wurde die Zeit bei GetFileAttributesEx und GetFileInformationByHandle für die Verarbeitung von etwa 165.000 Dateien mit zusammen > 3 TB von einer SSD gemessen. Die Messungen erfolgten einerseits nach Rechner-Neustart und dann beim erneuten Einlesen, andererseits mit Defender Antivirus (Windows 10, Echtzeitschutz + Manipulationsschutz) und ohne.

DateiInfoByHandle  
Neustart mit Defender 660 sec (!)
Neustart ohne Defender 11-14 sec
Zweitstart mit Defender 10-21 sec
Zweitstart ohne Defender 14-22 sec

GetFileAttributesEx
Neustart mit Defender 8 sec
Neustart ohne Defender 5 sec
Zweitstart mit Defender 5 sec
Zweitstart ohne Defender 5 sec

Der Defender Antivirus macht GetFileInformationByHandle ja fast unbrauchbar. Gibt es da ein Gegenmittel?

himitsu 2. Apr 2024 15:42

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Benmik (Beitrag 1535210)
Gibt es da ein Gegenmittel?

Nicht alles einzeln abfragen und dafür auch noch jede Datei öffnen, damit der Defender jeder Live-Scanner nicht gezwungen wird sich alle Dateien anzusehn :roll: :freak:


MSDN-Library durchsuchenFindFirstFileEx mit FIND_FIRST_EX_LARGE_FETCH

himitsu 2. Apr 2024 15:44

AW: GetFileSize - welches ist die bessere Funktion?
 
[deleted]

Benmik 2. Apr 2024 17:29

AW: GetFileSize - welches ist die bessere Funktion?
 
Schwer zu verstehen. Wie soll das gehen, nicht alle einzeln abzufragen? Ein Test mit dem direkten Aufruf von FindFirstFileExW ergab Zeiten zwischen 13 und 19 Sekunden, also wesentlich langsamer als GetFileAttributesEx. Der Aufruf von GetFileInformationByHandle lässt sich nicht umgehen, da ich die Anzahl der Links und den File Index benötige.

Die Dateigröße benötige ich nur, um festzustellen, ob Dateigleichheit in Frage kommt. Immerhin weiß ich jetzt, dass es etwas bringt, die Dateigrößen zuerst mit GetFileAttributesEx zu ermitteln, um alle diejenigen Dateigrößen auszusondern, die nur einmal vorkommen.

jaenicke 2. Apr 2024 18:31

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Benmik (Beitrag 1535215)
Schwer zu verstehen. Wie soll das gehen, nicht alle einzeln abzufragen? Ein Test mit dem direkten Aufruf von FindFirstFileExW ergab Zeiten zwischen 13 und 19 Sekunden, also wesentlich langsamer als GetFileAttributesEx.

Du fragst aber nicht etwa jede Datei einzeln so ab, oder?

Es geht ja eben darum, dass du die Anzahl der Abfragen reduzierst. Sprich dass du auf diese Weise gleich alle Dateien in einem Verzeichnis durchgehst.

Benmik 2. Apr 2024 21:00

AW: GetFileSize - welches ist die bessere Funktion?
 
Wie soll ich die nicht alle einzeln abfragen? Ich brauche die Daten für jede einzelne Datei. Ich habe eine Klasse
Delphi-Quellcode:
TDat
und eine
Delphi-Quellcode:
TObjectList<TDat>
, lese die Dateien mittels
Delphi-Quellcode:
TDirectory.GetFiles
in ein
Delphi-Quellcode:
TStringDynArray
ein und lege für jede Datei eine Instanz von TDat an. Bisher habe ich das mit GetFileInformationByHandle gemacht und von allen Dateien die entsprechenden Felder gefüllt; jetzt denke ich, dass ich viel Zeit spare, wenn ich mit GetFileAttributesEx erst einmal die herausfiltere, deren Bytegröße nur einmal vorkommt, und erst dann die verbliebenen mit GetFileInformationByHandle bearbeite. Das wäre nicht nötig, wenn der Defender Antivirus die Aktion nicht so wahnsinnig verlangsamen würde, aber da ist vermutlich nichts zu machen.

Uwe Raabe 2. Apr 2024 21:11

AW: GetFileSize - welches ist die bessere Funktion?
 
Du könntest das TDirectory.GetFiles overload nehmen, das ein TFilterPredicate akzeptiert. In dem Filter hast du Zugriff auf SearchRec.Size.

jbg 2. Apr 2024 22:05

AW: GetFileSize - welches ist die bessere Funktion?
 
Wie öffnest du das File-Handle für GetFileInformationByHandle? Man kann bei WinAPI.Windows.CreateFile() statt GENERIC_READ ein FILE_READ_ATTRIBUTES mitgeben. Dann ist CreateFile um einiges schneller. Und der Defender weiß, dass du dich nicht für den Inhalt der Datei interessierst.

Ein Test mit 69669 Dateien liefert bei mir:

Mit FILE_READ_ATTRIBUTES (Kalt):
CreateFile 1,696 Sekunden
GetFileInformationByHandle 0,275 Sekunden
CloseHandle 0,353 Sekunden

Mit GENERIC_READ (Kalt) (Defender braucht einen ganzen CPU-Kern):
CreateFile 217,032 Sekunden
GetFileInformationByHandle 0,451 Sekunden
CloseHandle 0,428 Sekunden

Übrigens die JclNTFS.pas NtfsGetHardLinkInfo Funktion nutzt GENERIC_READ, was sie somit auch extrem langsam macht, wenn ein Virenscanner vorhanden ist.


Hier der korrigierte JclNTFS.pas Code:
Delphi-Quellcode:
function NtfsGetHardLinkInfo(const FileName: string; var Info: TNtfsHardLinkInfo): Boolean;
var
  F: THandle;
  FileInfo: TByHandleFileInformation;
begin
  Result := False;
  F := CreateFile(PChar(FileName), {-->}FILE_READ_ATTRIBUTES{<--}, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  if F <> INVALID_HANDLE_VALUE then
  try
    ResetMemory(FileInfo, SizeOf(FileInfo));
    if GetFileInformationByHandle(F, FileInfo) then
    begin
      Info.LinkCount := FileInfo.nNumberOfLinks;
      Info.FileIndexHigh := FileInfo.nFileIndexHigh;
      Info.FileIndexLow := FileInfo.nFileIndexLow;
      Result := True;
    end;
  finally
    CloseHandle(F);
  end
end;

Benmik 2. Apr 2024 22:06

AW: GetFileSize - welches ist die bessere Funktion?
 
@Uwe Raabe: Jesus Christus. Das drückt die Zeit auf 2 Sekunden bei Neustart; bei Zweitstart und ausgeschaltetem Defender auf 0,7 Sekunden. Ganz abgesehen davon, dass man die Dateien ja sowieso einlesen muss.

Jetzt erinnere ich mich auch, dass ich damals das SearchRec bei Predicate gesehen hatte, aber das wäre mir im Leben nicht mehr eingefallen. Alle Achtung, Herr Raabe. :thumb:

Benmik 2. Apr 2024 22:44

AW: GetFileSize - welches ist die bessere Funktion?
 
Andreas, das ist natürlich auch genial. Und das Beste ist, dass ich es mit Uwes Rat kombinieren kann.
Meine Ergebnisse sind:

DateiInfoByHandle
Neustart mit Defender20 sec
Neustart ohne Defender12 sec
Zweitstart mit Defender19 sec
Zweitstart ohne Defender19 sec

Interessant, dass die Routine nach einem Neustart sogar schneller ist, aber dafür gibt es vermutlich auch eine Erklärung.

Erst jetzt fällt mir auf, dass es auch GetFileInformationByHandleEx mit dem Parameter FileInformationClass gibt. Da wäre FileIdInfo interessant, das aber leider nicht die Anzahl der Hardlinks mitliefert, die ich brauche. Anscheinend gibt es aber die Ex-Version nicht bei Delphi. Könnte man nachbauen, aber ist für mich vermutlich unnötig.

Jedenfalls bin ich ein großes Stück weitergekommen, hätte ich nicht gedacht. Vielen Dank euch beiden.

Offtopic: Ich bin immer noch ein ganz großer Fan von AsyncCalls und habe es nach wie vor in Verwendung. :thumb:

himitsu 3. Apr 2024 04:44

AW: GetFileSize - welches ist die bessere Funktion?
 
Es gibt einen FeatureRequest, das SearchRec (oder eine Alternative) auch als Result einer der Suchfunktionen zu bekommen (TArray<Irgendwas>), aber ob sowas Sinnvolles jemals eingebaut wird?


Zitat:

FILE_READ_ATTRIBUTES
Also im Prinzip auch eine Lösung, für den bereit genannten Grund.
* Wenn man nicht auf den Dateiinhalt zugreifen will, muß der Virenscanner auch nicht den Dateiinhalt prüfen.

Bei NTFS sind viele Daten bereits in der MFT hinterlegt, also mit etwas Glück auch gleich für viele Dateien in einem Speicherbereich, so dann nicht für jede Datei einzeln kreuz und quer von sonstwo Daten in kleinen Stückchen geladen werden müssen.

Man könnte auch die MFT direkt auslesen, was am Schnellsten ginge, aber dafür sind höhere Rechte nötig (Admin), was dieses Vorhaben etwas unpraktisch gestaltet, davon abgesehn, dass man es wohl alles selbst machen muß, da die passende WinAPI fehlt.

Zitat:

Ganz abgesehen davon, dass man die Dateien ja sowieso einlesen muss.
Muß man?

Benmik 3. Apr 2024 11:53

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von himitsu (Beitrag 1535238)
Man könnte auch die MFT direkt auslesen, was am Schnellsten ginge, aber dafür sind höhere Rechte nötig (Admin), was dieses Vorhaben etwas unpraktisch gestaltet, davon abgesehn, dass man es wohl alles selbst machen muß, da die passende WinAPI fehlt.

Ja, das direkte Auslesen der MFT ist schon lange ein Traum von mir, und ich habe da schon einige Arbeit hineingesteckt. Der einzige wirklich hilfreiche Code, den ich finden konnte, ist der von Alexander Freudenberg; den bekam ich auch gut ans Laufen, aber nicht völlig zuverlässig. Ich suche immer noch nach etwas Besserem; vielleicht hat sich da ja etwas getan und jemand hier weiß davon? Vielleicht Andreas?

Damit wären wir auch wieder ein bisschen mehr on topic, denn unter den erwähnten NTFS-Tools von Freudenberg findet sich auch NTFSTree, das Dateien mit Größenangabe unter Zugriff auf die MFT auflistet. Herunterzuladen hier.

Zitat:

Zitat von himitsu (Beitrag 1535238)
Zitat:

Ganz abgesehen davon, dass man die Dateien ja sowieso einlesen muss.
Muß man?

Einlesen muss man die Dateien, also ihren Inhalt, vielleicht im strengen Wortsinn nicht, aber auflisten und bestimmte Attribute auslesen schon. Jedenfalls verwende ich
Delphi-Quellcode:
TDirectory.GetFiles
sowieso, und wenn ich dabei die Dateigröße "umsonst" mitbekomme, ist das prima.

himitsu 3. Apr 2024 12:12

AW: GetFileSize - welches ist die bessere Funktion?
 
Jupp, ich hatte es vor einer Weile auch mal gemacht.

Mit Result:=False es nicht ins Result-Array aufnehmen
und den Filter als anonyme Methode, in welcher ich dann mein eigenes Record-Array selbst gefüllt hatte. (brauchte das Änderungsdatum, und in den normalen Results steht ja immer nur der Name)

jaenicke 3. Apr 2024 18:56

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Benmik (Beitrag 1535258)
Ich suche immer noch nach etwas Besserem; vielleicht hat sich da ja etwas getan und jemand hier weiß davon?

Ich hatte diesen hier angeschaut:
https://github.com/DougRogers/NTFSDi...em/tree/master

Benmik 3. Apr 2024 22:11

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von jaenicke (Beitrag 1535269)

Danke dir. Leider kann ich keine der C-Sprachen. Dort ist die Code-Situation viel günstiger, aber bei Delphi besteht kein Interesse offenbar oder keiner veröffentlich was.

Benmik 3. Apr 2024 22:14

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von jbg (Beitrag 1535224)
Man kann bei WinAPI.Windows.CreateFile() statt GENERIC_READ ein FILE_READ_ATTRIBUTES mitgeben.

Wenn ich die Dokumentation richtig verstehe, ist
Delphi-Quellcode:
0
sogar noch besser:
Zitat:

Wenn dieser Parameter null ist, kann die Anwendung bestimmte Metadaten wie Datei-, Verzeichnis- oder Geräteattribute abfragen, ohne auf diese Datei oder das Gerät zuzugreifen, auch wenn GENERIC_READ Zugriff verweigert worden wäre.

jbg 3. Apr 2024 23:26

AW: GetFileSize - welches ist die bessere Funktion?
 
Zitat:

Zitat von Benmik (Beitrag 1535279)
Wenn ich die Dokumentation richtig verstehe, ist
Delphi-Quellcode:
0
sogar noch besser

Hat mich jetzt mal interessiert, was denn der Unterschied ist. Und siehe da...

Im Code von CreateFileW wird vor dem Aufruf von NtCreateFile der "Access" Parameter mit 0x00100080 ge-OR-t. Das wäre also NtCreateFile(Access or (SYNCHRONIZE or FILE_READ_ATTRIBUTES), ...).
Zitat:

or eax,$00100080
push dword ptr [esp+$1c]
mov [esp+$28],eax
push dword ptr [ebp+$08]
push ecx
push $00
lea ecx,[esp+$40]
push ecx
lea ecx,[esp+$0080]
push ecx
push eax
lea eax,[esp+$48]
push eax
call dword ptr [$768700c4] => NtCreateFile
Auch im wine Code findet man dies.

0 hat also die gleiche Bedeutung wie "SYNCHRONIZE or FILE_READ_ATTRIBUTES". Es ist jetzt also nur Geschmackssache ob "CreateFile(FILE_READ_ATTRIBUTES, ...)" oder "CreateFile(0, ...)" eine besser Aussage trifft, was die Intention des Codes ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:19 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