Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Altes Thema kurze Frage zu FileAge (https://www.delphipraxis.net/178844-altes-thema-kurze-frage-zu-fileage.html)

cramer 31. Jan 2014 08:27

Delphi-Version: 2006

Altes Thema kurze Frage zu FileAge
 
Hallo,

auf der Suche nach dem Sommer/Winterzeit Unterschied beim Datei Änderungszeitpunkt in unterschiedlichen Filesystemen stellt sich mir die Frage nach der Auflösung von fileAge.

qFiles = Netware Volume
zFiles = NTFS Volume
Delphi-Quellcode:
qAge := fileAge( qFile );
zAge := fileAge( zFile );
qtime := FileDateToDateTime(qAge);
ztime := FileDateToDateTime(zAge);
difAge := abs( qAge - zAge );
difSec := SecondsBetween(qTime,zTime);
MyDebug('DifSec ' + IntToStr(difSeconds) + ' - DifAge ' + IntToStr(DifAge) );
[9656] myDebug DifSec 3599 - DifAge 2048
[9656] myDebug DifSec 3600 - DifAge 2048

difAge ergibt bei einer Zeitdifferenz von 1 Stunde immer 2048
difSec ergibt bei einer Zeitdifferenz von 1 Stunde 3599/3600 *
* je nach Abschneiden der Millisekunden durch die buggy SecondsBetween function

Nach welchen Kriterien wird denn der FileAge Integer gebaut,
daß sich ein Faktor von ca. 1:1,75 zu den Sekunden ergibt?

samso 31. Jan 2014 11:21

AW: Altes Thema kurze Frage zu FileAge
 
Ich verstehe Deine Frage nicht wirklich.
Zu dem Problem Sommerzeit/Winterzeit kann ich jedoch etwas beitragen. Bei der Berechnung des Dateidatums hat man es sich unter Windows leider sehr einfach gemacht (FileAge benutzt FileTimeToLocalFileTime). Zunächst muss man wissen, dass einige Dateisystem die Zeiten intern als UTC und einige als lokale Zeit speichern. Bei FAT/FAT32/Netware wird die Zeit als lokale Zeit, bei NTFS und CDFS als UTC gespeichert. Fileage rechnet immer auf die lokale Zeit um. Bei FAT muss also lediglich die lokale Zeit 1:1 ausgegeben werden. Bei NTFS muss hingegen gerechnet werden. Bei der Berechnung wird aber nicht der UTC-Bias zum Zeitpunkt des Dateidatums herangezogen, sondern der aktuelle UTC-Bias. Das führt dazu, dass sich nach der Sommerzeit/Winterzeit-Umschaltung das Dateidatum aller Dateien bei einem UTC-Filesystem ändern. Will man die korrekte lokale Zeit bekommen, ist die Funktion Fileage unbrauchbar. Um die korrekte lokale Zeit zu bekommen, muss zunächst das UTC-Dateidatum ermittelt werden. Dann muss der passende UTC-Bias dazu berechnet werden. Im nächsten Schritt kann dann mit dem UTC-Bias das lokale Dateidatum berechnet werden.
Die Auflösung des Dateidatums bei FAT/FAT32 ist 2 Sekunden. Bei NTFS ist es theoretisch 100 Nanosekunden.

cramer 4. Feb 2014 16:29

AW: Altes Thema kurze Frage zu FileAge
 
Sorry, bin erst jetzt wieder im Büro.:oops:

Meine Frage zielte auf den seltsamen Wert 2048 = 1 Stunde = 3600 Sekunden hin.
Angenommen Borland ermittelt den Wert gem. FAT-Spezifikation und 2 Sekunden Auflösung, hätte ich 1800 erwartet.

Ist aber auch egal, ich ermittle nun grob die Differenz nach FileAge und wenn diese < 2050 liegt, gehts in die Feinheiten und Sekunden.

Trotzdem Danke für die Infos.:thumb:

Sir Rufo 4. Feb 2014 16:42

AW: Altes Thema kurze Frage zu FileAge
 
MSDN-Library durchsuchenFILETIME
Zitat:

It is not recommended that you add and subtract values from the FILETIME structure to obtain relative times. Instead, you should copy the low- and high-order parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic on the QuadPart member, and copy the LowPart and HighPart members into the FILETIME structure.
Mehr gibt es da eigentlich nicht zu sagen ;)

cramer 4. Feb 2014 19:33

AW: Altes Thema kurze Frage zu FileAge
 
Na ja, aber vielleicht noch zu fragen, soll das heißen, der sogenannte FileAge integer ist in wirklichkeit eine Filetime Struktur?

Gibt es denn Erfahrungswerte mit welcher API man unter Windows z.B. bei rund 600000 Dateien das Änderungsdatum zweier Dateien am schnellsten unter Berücksichtigung der unterschiedlichen Filesysteme und der lokalen Zeit ermitteln und vergleichen kann?

himitsu 4. Feb 2014 19:55

AW: Altes Thema kurze Frage zu FileAge
 
Das alte DOS-Format sollte man gleich vergessen.

MSDN-Library durchsuchenGetFileTime

Es kommt auch erstmal darauf an, um welches Datum es sich handelt, denn die haben teilweise eine unterschiedliche Auflösung.
Dann müsste man auslesen um welches Dateisystem (Treiber) es sich handelt und eventuell wie der eingestellt ist, denn NTFS hat z.B. für SSDs einen anderen Modus, wo nicht mehr jedes Datum gespeichert wird, bzw. manchmal auch verzögert oder in einer anderen Auflösung.

Die Zahlenwerte ändern sich aber nicht, um mal auf deine 1800 anzuspielen ... bei halber Auflösung gibt es einfach nur jeden zweiten Wert nicht.


Entsprechend der Dateisysteme/Einstellungen muß man beim Vergleichen eine ensprechende Tolleranz zulassen.

Eventuell muß man auch noch die Zeitzone umrechnen, wenn man über zwei Partitionen hinweg vergleicht.


PS: Ich hatte damals aufgegeben, als ich tagelang versuchte das umzusetzen.

hathor 5. Feb 2014 09:29

AW: Altes Thema kurze Frage zu FileAge
 
Es gibt verschiedene Versionen von FILEAGE:

Alt:
function FileAge(const FileName: string): Integer; overload;
Neu:
function FileAge(const FileName: string; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;

Siehe:
http://docwiki.embarcadero.com/Libra...sUtils.FileAge
http://docwiki.embarcadero.com/CodeE...r_%28Delphi%29

Ausserdem:
Bug NOVELL:
http://forum.delphi-treff.de/index.p...&threadID=9416

samso 5. Feb 2014 10:15

AW: Altes Thema kurze Frage zu FileAge
 
Zitat:

Zitat von cramer (Beitrag 1246679)
Gibt es denn Erfahrungswerte mit welcher API man unter Windows z.B. bei rund 600000 Dateien das Änderungsdatum zweier Dateien am schnellsten unter Berücksichtigung der unterschiedlichen Filesysteme und der lokalen Zeit ermitteln und vergleichen kann?

Die Windows-Api/Delphi kann das überhaupt nicht (wie ich schon erläuterte). Das muss man selber machen. Perfekt bekommt man das nicht hin, weil FAT/FAT32/Novell halt leider lokale Zeiten speichern und man deshalb nicht mehr eindeutig zu UTC zurück kommt.
Der Totalcommander versucht das Problem mit Hilfe einer Toleranzschwelle von einer Stunde zu lösen. Das geht aber spätestens schief, wenn man es mit unterschiedlichen Zeitzonen zu tun hat.
Das Performance-Problem ist doch nicht die Berechnung, sondern der Flaschenhals ist der Directory-Scan. Bei jedem FileAge wird erneut das Directory durchsucht. Das dauert "ewig" im Vergleich zu einer umfangreichen Berechnung des Dateidatums (also mit korrekte Berücksichtigung des UTC-Bias und dem zugrunde liegenden Dateisystems).


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