AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

GetFileSize - welches ist die bessere Funktion?

Ein Thema von Glados · begonnen am 20. Okt 2017 · letzter Beitrag vom 4. Apr 2024
Antwort Antwort
Seite 4 von 5   « Erste     234 5      
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#31

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 2. Apr 2024, 23:05
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;
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
557 Beiträge
 
Delphi 12 Athens
 
#32

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 2. Apr 2024, 23:06
@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.

Geändert von Benmik ( 2. Apr 2024 um 23:54 Uhr)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
557 Beiträge
 
Delphi 12 Athens
 
#33

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 2. Apr 2024, 23:44
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#34

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 3. Apr 2024, 05:44
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?
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 3. Apr 2024 um 05:50 Uhr)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
557 Beiträge
 
Delphi 12 Athens
 
#35

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 3. Apr 2024, 12:53
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:
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 TDirectory.GetFiles sowieso, und wenn ich dabei die Dateigröße "umsonst" mitbekomme, ist das prima.

Geändert von Benmik ( 3. Apr 2024 um 13:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#36

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 3. Apr 2024, 13:12
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)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#37

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 3. Apr 2024, 19:56
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
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
557 Beiträge
 
Delphi 12 Athens
 
#38

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 3. Apr 2024, 23:11
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.
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
557 Beiträge
 
Delphi 12 Athens
 
#39

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 3. Apr 2024, 23:14
Man kann bei WinAPI.Windows.CreateFile() statt GENERIC_READ ein FILE_READ_ATTRIBUTES mitgeben.
Wenn ich die Dokumentation richtig verstehe, ist 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.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#40

AW: GetFileSize - welches ist die bessere Funktion?

  Alt 4. Apr 2024, 00:26
Wenn ich die Dokumentation richtig verstehe, ist 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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 5   « Erste     234 5      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:07 Uhr.
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