Entwickler-Ecke

Dateizugriff - Letzte Änderung einer Datei Datum auslesen


smepal - Do 08.05.08 12:29
Titel: Letzte Änderung einer Datei Datum auslesen
Hallo,
also ich arbeite schon seit einiger Zeit an einem Programm, welches einen Ordner mit Unterordnern auf einem Server mit einem auf den jeweiligen PCs vergleichen soll.
Das Rätsel was sich mir dabei auftut ist folgendes:
Und zwar stehe ich vor dem Problem, wie ich verfahren soll, wenn eine Datei sowohl auf dem Server als auch auf dem PC vorliegt.
Irgendwie müsste ich die Versionen abgleichen. Ich dachte mir zunächst, das ginge am einfachsten über das Datum der letzten Änderung. Das wird auf dem Server in einer Ini-Datei festgehalten, in der das Datum und die Uhrzeit des Hochladens steht.
Dies soll nun mit einem Datum auf dem PC verglichen werden!

Jetzt ist die Frage, wie kann ich das ermitteln?
Mit dieser Funktion bekomme ich leider nur das Datum des letzten Zugriffs. Das bringt mir gar nichts, da sich das laufend ändert!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
unction GetFileLastAccessTime(Path: string): TDateTime;
var
  hFile: THandle;
  rStructur: TWin32FindData;
  rFileTime: TFileTime;
  dwLastAccess: cardinal;

begin
  Result := 0;
  hFile := Windows.FindFirstFile(pchar(Path), rStructur);
  if INVALID_HANDLE_VALUE <> hFile
  then begin
    Windows.FindClose(hFile);
    { FILETIME in lokales FILETIME-Format konvertieren }
    FileTimeToLocalFileTime(rStructur.ftLastAccessTime, rFileTime);
    { lokales FILETIME-Format ins DOS-Format konvertieren }
    FileTimeToDosDateTime(rFileTime, LongRec(dwLastAccess).Hi, LongRec(dwLastAccess).Lo);
    { DOS-Format in ein Delphi-Format konvertieren }
    Result := FileDateToDateTime(dwLastAccess);
  end;

end{function GetFileLastAccessDate() ...}


Auch das Datei-Erstellungsdatum auszulesen würde nichts bringen, da sich das zum einen auf dem Server laufend ändert und zum anderen nach dem Bearbeiten der Datei auf dem PC nicht geändert wird.
Dazu würde diese Funktion dienen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
function GetCreationTimeOfFile(const AFileName: String;): TDateTime;
var
  SR: TSearchRec;
  SystemTime: TSystemTime;
  NewCreationTime: TFileTime;
begin
  Result:=0;
  if FindFirst(AFileName, faAnyFile, SR)=0 then
  try
   IF (Windows.FileTimeToLocalFiletime(SR.FindData.ftCreationTime, NewCreationTime) and
           Windows.FileTimeToSystemTime(NewCreationTime, SystemTime)) Then
    Result:=Encodedate(SystemTime.wYear,
                       SystemTime.wMonth,
                        SystemTime.wDay) +
            Encodetime(SystemTime.wHour,
                       SystemTime.wMinute,
                       SystemTime.wSecond,
                       SystemTime.wMilliseconds);
  finally
   SysUtils.FindClose(SR)
  end;
end;

Ich brauche also eine Funktion, die mir das Datum der letzten Änderung ausgibt!

Habe nur leider keine Idee wie!


Martok - Do 08.05.08 13:51

Das hätte man ja wohl ableiten können :roll:


Delphi-Quelltext
1:
2:
3:
4:
function GetFileLastAccessTime(Path: string): TDateTime;
[...]
    FileTimeToLocalFileTime(rStructur.ftLastAccessTime, rFileTime);
[...]



Delphi-Quelltext
1:
2:
3:
4:
function GetCreationTimeOfFile(const AFileName: String;): TDateTime;
[...]
   IF (Windows.FileTimeToLocalFiletime(SR.FindData.ftCreationTime, NewCreationTime) and
[...]

Und jetzt mal gucken was der 3. Time-Wert in dieser Struktur ist...
MSDN hat folgendes geschrieben:
ftLastWriteTime
FILETIME structure containing the time that the file was last written to. The time is in UTC format; the FILETIME members are zero if the file system does not support this time member.

Einmal tauschen, fertig.

Naja, und die Server-Ini dürfte klar sein. "GET /times.ini" am Anfang (evtl. irgendein Lockfile setzen), auslesen, vergleichen, Synchen, (Lockfile wieder entfernen).


smepal - Do 08.05.08 15:30

Vielen Dank für die Antwort!

Gut! Das funktioniert soweit!
Dummerweise habe ich immer eine Differenz von 1 Sekunde! Die könnte ich beseitigen, indem ich einfach das TDatetime setze. Dann müsste ich allerdings von TDatetime 1 Sekunde abziehen!

Wie geht das?

//EDIT:
Sry geht mit incseconds()!