Einzelnen Beitrag anzeigen

BerndS

Registriert seit: 8. Mär 2006
Ort: Jüterbog
491 Beiträge
 
Delphi 12 Athens
 
#1

MoveFile verändert auf einmal CreationTime unter W7

  Alt 14. Jan 2013, 08:12
Hallo,
ich habe mich gewundert, dass alte Funktionen zur Archivierung alter Backupdateien mit einmal nicht mehr funkionieren, da CreationTime zur Bildung des Namens der Backupdatei verwendet wurde (Backup_JJJJMMTT_HHMM.IBK z.B.). Das lässt sich zwar durch Verwendung von
LastWriteTime fixen, aber die Anwender haben erst mal das Problem!!!

Dabei habe ich festgetellt, dass MoveFile unter folgenden Umständen ein (RenameFile aus SysUtils) wohl einen Bug haben muss?!

Der Ablauf beim Backup.
1. Es ist eine alte Backupdatei vorhanden.
2. Es wird eine neue Backupdatei temporär angelegt.
3. Die alte wird umbenannt (z.B.in BackupOld).
4. Die temporäre Datei wird in Backup umbennant.

Jetzt hat die letztere den gleichen Zeitstempel bei CreationTime wie die BackupOld.

Hier mal ein Demoprogramm, welches unter W7 (64 und 32) zum gleichen Ergebnis führt.
Delphi-Quellcode:
program TestFileDate;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, Windows,
  DateUtils;
const
  TestFilename = 'TestFileOrg.TXT';
  TestFilename2 = 'TestFileRen.TXT';
  TempFilename = 'TestFileNew.TMP';

  function FileTimeToDateTime(ft: TFileTime): TDateTime;
  var st : TSystemTime;
  begin
    FileTimeToLocalFileTime(ft,ft);
    FileTimeToSystemTime (ft, st);
    with st do
      result := EncodeDate(wYear, wMonth, wDay) +
        EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
  end;

  function DateTimeToFileTime(dt: TDateTime): TFileTime;
  var
    st : TSystemTime;
  begin
    with st do
      begin
        DecodeDate(dt, st.wYear, st.wMonth, st.wDay);
        DecodeTime(dt, st.wHour, st.wMinute, st.wSecond, st.wMilliSeconds);
      end;
    SystemTimeToFileTime (st, result);
    LocalFileTimeToFileTime(result,result);
  end;

  procedure WriteFileTile(AFileName: string);
  var
    F:TFileStream;
    CreateTime, LastWriteTime: TFileTime;
  begin
    F := TFileStream.Create(AFileName, fmOpenRead);
    try
      GetFileTime(F.Handle,@CreateTime, nil,@LastWriteTime);
    finally
      F.Free;
    end;
    WriteLn(AFileName,
            ' Created:',
            DateTimeToStr(FileTimeToDateTime(CreateTime)),
            ' geaendert:' ,DateTimeToStr(FileTimeToDateTime( LastWriteTime)));
  end;
  procedure CreateTestFile(AFileName: string;AFileTime: TDateTime);
  var
    F:TFileStream;
    FT:TFileTime;
  begin
    F := TFileStream.Create(AFileName, fmCreate);
    try
      F.Write(AFileName[1],Length(AFileName));
      FT := DateTimeToFileTime(AFileTime);
      SetFileTime(F.Handle,@FT, nil, @FT);
    finally
      F.Free;
    end;
    WriteFileTile(AFileName)
  end;
begin
  try
    // alte Dateien löschen
    DeleteFile(TestFilename);
    DeleteFile(TestFileName2);
    WriteLn('1. Datei mit altem Datum anlegen');
    CreateTestFile(TestFilename,IncMinute(IncHour(IncDay(IncMonth(IncYear(Now, - 1),-1),-1),-1),-1));
    WriteLn('2. Datei mit aktuellem Datum anlegen');
    CreateTestFile(TempFilename,Now);
    WriteLn('Rename: ',TestFilename,' -> ', TestFileName2);
    RenameFile(TestFilename, TestFileName2);
    WriteFileTile(TestFileName2);
    WriteFileTile(TempFilename);
    RenameFile(TempFilename,TestFilename);
    WriteLn('Rename: ',TempFilename,' -> ',TestFilename);
    WriteFileTile(TestFilename);
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Hier noch die Ausgabe in der Konsole:
Code:
1. Datei mit altem Datum anlegen
TestFileOrg.TXT Created:13.12.2011 07:03:16 geaendert:13.12.2011 07:03:16
2. Datei mit aktuellem Datum anlegen
TestFileNew.TMP Created:14.01.2013 08:04:16 geaendert:14.01.2013 08:04:16
Rename: TestFileOrg.TXT -> TestFileRen.TXT
TestFileRen.TXT Created:13.12.2011 06:41:21 geaendert:13.12.2011 07:03:16
TestFileNew.TMP Created:14.01.2013 08:04:16 geaendert:14.01.2013 08:04:16
Rename: TestFileNew.TMP -> TestFileOrg.TXT
TestFileOrg.TXT Created:13.12.2011 07:03:16 geaendert:14.01.2013 08:04:16
Kann das jemand nachvollziehen?

Gruß Bernd
  Mit Zitat antworten Zitat