2016-06-23 10 views
0

Ich möchte das aktualisierte Datum einer Datei ändern. Also verwende ich den folgenden Code, um es zu tun.Delphi FileSetDate ist fehlerhaft

procedure FileDateUpdate; 
var 
    date1,date2 : TDateTime; 
    file1, file2 : string; 
begin 
    file1 := 'G:\ab.pdf'; 
    file2 := 'G:\Shirish\ab.pdf'; 
    FileAge(file1, date1); 
    FileSetDate(file2, DateTimeToFileDate(date1)); 
    Fileage(file2, date2); 
    ShowMessage('File1 date: '+ DateTimeToStr(date1) + '|| File2 date: '+ DateTimeToStr(date2)); 
end; 

Ausgabe

File1 date: 24-05-2016 11:34:35|| File2 date: 24-05-2016 11:34:34 

Interessanter sind die Termine nie gleich auf beiden Dateien.

Wenn ich die Methode veraltet FileAge es gut funktioniert

i := FileAge(file1); 
FileSetDate(file2, i); 
j := FileAge(file2); 
ShowMessage('File1 date: '+ DateTimeToStr(FileDateToDateTime(i)) + '|| File2 date: '+ DateTimeToStr(FileDateToDateTime(j))); 

Ausgabe

File1 date: 24-05-2016 11:34:36|| File2 date: 24-05-2016 11:34:36

+0

Wenn die Dateien auf FAT32 Dateisystem sind, kann das Problem sein. Wenn sie es dann sind, versuchen Sie es auf NTFS. – jano152

+0

Ich habe Delphi XE8 jetzt nicht auf meinen Rechnern installiert, also habe ich das in Delphi Seattle und Delphi getestet und in beiden Fällen funktioniert der Code sowohl für NTFS- als auch für FAT32-Partitionen. Aber es gibt einen Fata-Flow in deinem Code. Sie überprüfen die Rückgabewerte verwendeter Methoden nicht und können daher nicht sicher sein, ob alle erfolgreich waren. A nehme an, dass Ihr Programm die letzte Aktualisierungsinformation Ihrer zweiten Datei möglicherweise nicht aktualisiert, da es zu diesem Zeitpunkt möglicherweise noch von einem Programm geöffnet wird. – SilverWarior

+0

MSDN sagt auch: "* Nicht alle Dateisysteme können die Erstellungs- und letzten Zugriffszeiten aufzeichnen und nicht alle Dateisysteme zeichnen sie auf die gleiche Weise auf. Zum Beispiel hat die Erstellungszeit bei FAT eine Auflösung von 10 Millisekunden, ** Schreibzeit hat eine Auflösung von 2 Sekunden **, und Zugriffszeit hat eine Auflösung von 1 Tag (wirklich, das Zugriffsdatum). ** Daher kann die 'GetFileTime'-Funktion möglicherweise nicht die gleiche Datei Zeitinformation mit' SetFileTime' zurückgeben ** NTFS verzögert Aktualisierungen der letzten Zugriffszeit für eine Datei um bis zu einer Stunde nach dem letzten Zugriff. * " –

Antwort

0

Im Laufe der Zeit habe ich einige Funktionen von www in einigen Einheiten gesammelt haben. (Ich erinnere mich nicht, wenn ich einige von ihnen geändert habe).

Vielleicht ist dies eine Hilfe Chance sein könnte (Ich habe dies für den Wandel der „Puvananthiran delphi Notizblock“ für aktualisiert die Datei entsprechend geladen mit dem Datum der letzten Änderung) .`

unit FileTimeUtils; 

interface 

uses 
    SysUtils, Windows; 

function DateTimeToFileTime(const aDt: TDateTime): TFileTime; 
function FileTimeToDateTime(ft: TFileTime): TDateTime; 

procedure DaDateTimeToFileTime(const aDt: TDateTime; var aFileTime: TFileTime); 
procedure DaFileTimeToDateTime(ft: TFileTime; var aDateTime: TDateTime); 

function FindLastWrittenFile(const aDir, aSearch: String): String; 
function GetFileDateTime(const aFileName: String; var aCreationTime, aLastAccessTime, aLastModificationTime: TDateTime): Boolean; 
function SetFileDateTime(const aFileName: String; aNewCreationTime, aNewAccessTime, aNewModifyTime: TDateTime): Boolean; 

function GetCreationTime(const aFileName: String): TDateTime; 
function GetLastAccessTime(const aFileName: String): TDateTime; 
function GetLastWriteTime(const aFileName: String): TDateTime; 

function SetCreationTime(const aFileName: String; aNewCreationTime: TDateTime): Boolean; 
function SetLastAccessTime(const aFileName: String; aNewAccessTime: TDateTime): Boolean; 
function SetLastWriteTime(const aFileName: String; aNewModifyTime: TDateTime): Boolean; 

implementation 


function DateTimeToFileTime(const aDt: TDateTime): TFileTime; 
var 
    st: TSystemTime; 
begin 
    DateTimeToSystemTime(aDt, st); 
    if not (SystemTimeToFileTime(st, Result) and LocalFileTimeToFileTime(Result, Result)) then 
    RaiseLastOSError 
end; 


function FileTimeToDateTime(ft: TFileTime): TDateTime; 
var 
    st: TSystemTime; 
begin 
    if not (FileTimeToLocalFileTime(ft, ft) and FileTimeToSystemTime(ft, st)) then 
    RaiseLastOSError; 
    Result:= SystemTimeToDateTime(st) 
end; 


procedure DaDateTimeToFileTime(const aDt: TDateTime; var aFileTime: TFileTime); 
begin 
    aFileTime:= DateTimeToFileTime(aDt) 
end; 


procedure DaFileTimeToDateTime(ft: TFileTime; var aDateTime: TDateTime); 
begin 
    aDateTime:= FileTimeToDateTime(ft) 
end; 


function FindLastWrittenFile(const aDir, aSearch: String): String; 
var 
    Dir: String; 
    vR: TSearchRec; 
    LastWrite, LastWriteAllFiles: TDateTime; 
begin 
    {$Warnings Off} 
    Dir:= IncludeTrailingBackslash(aDir); 
    LastWriteAllFiles:= 0; 
    Result:= ''; 
    if FindFirst(Dir + aSearch, faAnyFile - faDirectory, vR) = 0 then 
    repeat 
     LastWrite:= FileTimeToDateTime(vR.FindData.ftLastWriteTime); 
     {$Warnings On} 
     if LastWrite > LastWriteAllFiles then 
     begin 
     LastWriteAllFiles:= LastWrite; 
     Result:= vR.Name 
     end 
    until FindNext(vR) <> 0; 
    SysUtils.FindClose(vR) 
end; 


function GetFileDateTime(const aFileName: String; var aCreationTime, aLastAccessTime, aLastModificationTime: TDateTime): Boolean; 
var 
    FileHandle: Cardinal; 
    CreationTime, LastAccessTime, LastWriteTime: TFileTime; 
begin 
    Result:= False; 
    FileHandle:= CreateFile(PChar(aFileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); 
    if FileHandle <> INVALID_HANDLE_VALUE then 
    try 
     Result:= GetFileTime(FileHandle, @CreationTime, @LastAccessTime, @LastWriteTime); 
     DaFileTimeToDateTime(CreationTime, aCreationTime); 
     DaFileTimeToDateTime(LastAccessTime, aLastAccessTime); 
     DaFileTimeToDateTime(LastWriteTime, aLastModificationTime) 
    finally 
     CloseHandle(FileHandle) 
    end 
end; { GetFileDateTime } 


function SetFileDateTime(const aFileName: String; aNewCreationTime, aNewAccessTime, aNewModifyTime: TDateTime): Boolean; 
var 
    FileHandle: Cardinal; 
    CreationTime, LastAccessTime, LastWriteTime: TFileTime; 
begin 
    Result:= False; 

    CreationTime := DateTimeToFileTime(aNewCreationTime); 
    LastAccessTime:= DateTimeToFileTime(aNewAccessTime); 
    LastWriteTime:= DateTimeToFileTime(aNewModifyTime); 

    FileHandle:= FileOpen(aFileName, fmOpenReadWrite or fmShareExclusive); 
    try 
    if SetFileTime(FileHandle, @CreationTime, @LastAccessTime, @LastWriteTime) then 
     Result:= True 
    finally 
    FileClose(FileHandle) 
    end 
end; { SetFileDateTime } 


function GetCreationTime(const aFileName: String): TDateTime; 
var 
    ffd: TWin32FindData; 
    dft: DWord; 
    LFT: TFileTime; 
    h: THandle; 
begin 
    Result:= 0; 
    h:= Windows.FindFirstFile(PChar(aFileName), ffd); 
    if INVALID_HANDLE_VALUE <> h then 
    begin 
    Windows.FindClose(h); 
    FileTimeToLocalFileTime(ffd.ftCreationTime, LFT); 
    FileTimeToDosDateTime(LFT, LongRec(dft).Hi, LongRec(dft).Lo); 
    Result:= FileDateToDateTime(dft) 
    end 
end; 


{------------------------------------------------------------------------------ 
    "GetLastAccessTime()" will return a given file's last access time 
    as a Delphi "TDateTime" type which you can convert to a string by using the 
    "DateTimeToStr()" function. For example: 

    MessageDlg('c:config.sys was last accessed on ' + 
    DateTimeToStr(GetLastAccessTime('c:config.sys')), 
    mtInformation, [mbOk], 0); 
------------------------------------------------------------------------------} 

function GetLastAccessTime(const aFileName: String): TDateTime; 
var 
    ffd: TWin32FindData; 
    dft: DWord; 
    LFT: TFileTime; 
    h: THandle; 
begin 
    Result:= 0; 
    // get file information 
    h:= Windows.FindFirstFile(PChar(aFileName), ffd); 
    if INVALID_HANDLE_VALUE <> h then 
    begin 

    // we're looking for just one file, 
    // so close our "find" 
    Windows.FindClose(h); 

    // convert the FILETIME to 
    // local FILETIME 
    FileTimeToLocalFileTime(ffd.ftLastAccessTime, LFT); 

    // convert FILETIME to 
    // DOS time 
    FileTimeToDosDateTime(LFT, LongRec(dft).Hi, LongRec(dft).Lo); 

    // finally, convert DOS time to 
    // TDateTime for use in Delphi's 
    // native date/time functions 
    Result:= FileDateToDateTime(dft) 
    end 
end; 


function GetLastWriteTime(const aFileName: String): TDateTime; 
var 
    ffd: TWin32FindData; 
    dft: DWord; 
    LFT: TFileTime; 
    h: THandle; 
begin 
    Result:= 0; 
    h:= Windows.FindFirstFile(PChar(aFileName), ffd); 
    if INVALID_HANDLE_VALUE <> h then 
    begin 
    Windows.FindClose(h); 
    FileTimeToLocalFileTime(ffd.ftLastWriteTime, LFT); 
    FileTimeToDosDateTime(LFT, LongRec(dft).Hi, LongRec(dft).Lo); 
    Result:= FileDateToDateTime(dft) 
    end 
end; 


function SetCreationTime(const aFileName: String; aNewCreationTime: TDateTime): Boolean; 
var 
    FileHandle: Cardinal; 
    CreationTime, LastAccessTime, LastWriteTime: TDateTime; 
    ftCreationTime, ftLastAccessTime, ftLastWriteTime: TFileTime; 
begin 
    Result:= False; 
    if not GetFileDateTime(aFileName, CreationTime, LastAccessTime, LastWriteTime) then 
    Exit; 

    ftCreationTime := DateTimeToFileTime(aNewCreationTime); 
    ftLastAccessTime:= DateTimeToFileTime(LastAccessTime); 
    ftLastWriteTime:= DateTimeToFileTime(LastWriteTime); 

    FileHandle:= FileOpen(aFileName, fmOpenReadWrite or fmShareExclusive); 
    try 
    if SetFileTime(FileHandle, @ftCreationTime, @ftLastAccessTime, @ftLastWriteTime) then 
     Result:= True 
    finally 
    FileClose(FileHandle) 
    end 
end; { SetCreationTime } 


function SetLastAccessTime(const aFileName: String; aNewAccessTime: TDateTime): Boolean; 
var 
    FileHandle: Cardinal; 
    CreationTime, LastAccessTime, LastWriteTime: TDateTime; 
    ftCreationTime, ftLastAccessTime, ftLastWriteTime: TFileTime; 
begin 
    Result:= False; 
    if not GetFileDateTime(aFileName, CreationTime, LastAccessTime, LastWriteTime) then 
    Exit; 

    ftCreationTime := DateTimeToFileTime(CreationTime); 
    ftLastAccessTime:= DateTimeToFileTime(aNewAccessTime); 
    ftLastWriteTime:= DateTimeToFileTime(LastWriteTime); 

    FileHandle:= FileOpen(aFileName, fmOpenReadWrite or fmShareExclusive); 
    try 
    if SetFileTime(FileHandle, @ftCreationTime, @ftLastAccessTime, @ftLastWriteTime) then 
     Result:= True 
    finally 
    FileClose(FileHandle) 
    end 
end; { SetLastAccessTime } 


function SetLastWriteTime(const aFileName: String; aNewModifyTime: TDateTime): Boolean; 
var 
    FileHandle: Cardinal; 
    CreationTime, LastAccessTime, LastWriteTime: TDateTime; 
    ftCreationTime, ftLastAccessTime, ftLastWriteTime: TFileTime; 
begin 
    Result:= False; 
    if not GetFileDateTime(aFileName, CreationTime, LastAccessTime, LastWriteTime) then 
    Exit; 

    ftCreationTime := DateTimeToFileTime(CreationTime); 
    ftLastAccessTime:= DateTimeToFileTime(LastAccessTime); 
    ftLastWriteTime:= DateTimeToFileTime(aNewModifyTime); 

    FileHandle:= FileOpen(aFileName, fmOpenReadWrite or fmShareExclusive); 
    try 
    if SetFileTime(FileHandle, @ftCreationTime, @ftLastAccessTime, @ftLastWriteTime) then 
     Result:= True 
    finally 
    FileClose(FileHandle) 
    end 
end; { SetLastWriteTime } 

end. 

die Nutzung ist einfach:

// For Test: Drag two files in executable program self 

program FileDateUpdate; 

{$APPTYPE CONSOLE} 

uses 
    Windows, FileTimeUtils; 

{$R *.res} 

var 
    FirstFile, UpdateFile, msg1, msg2: String; 
    CreationTime, LastWriteTime, LastAccessTime: TDateTime; 

begin 
    FirstFile := ParamStr(1); 
    UpdateFile:= ParamStr(2); 

    msg1:= 'First file is ' + FirstFile + ' - Second file is ' + UpdateFile; 

    msg1:= msg1 + #13#10 + #13#10 + 'Note: The second file get the date of first file...'; 

    msg2:= ' Confirm ?'; 

    if MessageBox(0, Pchar(msg1), Pchar(msg2), MB_YESNO + MB_ICONQUESTION) = IDYES then 
    begin 
    GetFileDateTime(FirstFile, CreationTime, LastAccessTime, LastWriteTime); 
    SetFileDateTime(UpdateFile, CreationTime, LastAccessTime, LastWriteTime) 
    end 
end. 
` 
+0

Wie beantwortet dies die Frage, ob FileSetDate richtig funktioniert oder nicht? –

+0

Es scheint offensichtlich. Aber ich hoffe, dass jemand die Mühe geschätzt hat, eine Antwort zu geben. Wenn Sie für einen Arbeitgeber arbeiten, können Sie nicht sagen, dass Sie nicht wissen, dass es filesetdate nicht funktioniert. Sie haben die Dringlichkeit, eine alternative Antwort zu geben. Und nach zwei Tagen scheint es nicht, dass jemand für eine Lösung geantwortet hat, die mit Filesetdate arbeitet oder nicht. Wenn ich der Autor der Frage gewesen wäre und du der Autor der Antwort, hättest du mich glücklich gemacht. Ich hätte +10 gegeben. Aber nicht jeder weiß Danke zu sagen und tut mir leid. –

+0

Das Poster hatte bereits einen Workaround und zeigte es in der Post. Die Frage bezog sich auf das spezifische Verhalten von FileSetDate, das Sie in Ihrer Antwort überhaupt nicht angesprochen haben. Vielleicht ist es an manchen Orten angebracht, eine Antwort über Katzenfutteraromen zu schreiben, wenn die Frage nach dem Verhalten einer bestimmten Katzenrasse fragt, aber wir sind nicht diese Seite. Wir beantworten zuerst die spezifische Frage und * dann *, wenn Sie eine Alternative haben, um zu empfehlen, dass Sie sie anbieten können. Sie haben die spezifische Frage noch nicht beantwortet. –