2010-08-16 59 views
2

我有一個實用程序比較源文件和目標文件的日期/時間。這在大多數情況下都適用,但在比較不同時區中文件的日期/時間時會失敗。所以我需要一個UTC日期時間例程。UTC支持比較2個文件日期/時間

從環視看來,Windows API GetFileTime將支持這一點。我也發現這個包裝程序,但它在Delphi 2010下編譯時在GetFileTime調用上崩潰。

任何想法?或者是否有人有處理UTC時區等代碼片段,我可以傳遞2個文件名,這將告訴我,如果他們不同?

function CompareFileTimes(File1, File2 : String) : LongInt; 
var 
    F1, F2   : THandle; 
    F1_CreateTime, 
    F1_LastAccess, 
    F1_LastWrite, 
    F2_CreateTime, 
    F2_LastAccess, 
    F2_LastWrite : PFileTime; 
begin 
    //Initialize all variables 
    F1 := 0; 
    F2 := 0; 

    //Since these are pointers, we have to 
    //allocate memory for the FileTime structures 
    GetMem(F1_CreateTime, SizeOf(TFileTime)); 
    GetMem(F1_LastAccess, SizeOf(TFileTime)); 
    GetMem(F1_LastWrite, SizeOf(TFileTime)); 
    GetMem(F2_CreateTime, SizeOf(TFileTime)); 
    GetMem(F2_LastAccess, SizeOf(TFileTime)); 
    GetMem(F2_LastWrite, SizeOf(TFileTime)); 

    //Fill the structures with nulls for now 
    FillChar(F1_CreateTime, SizeOf(TFileTime), #0); 
    FillChar(F1_LastAccess, SizeOf(TFileTime), #0); 
    FillChar(F1_LastWrite, SizeOf(TFileTime), #0); 
    FillChar(F2_CreateTime, SizeOf(TFileTime), #0); 
    FillChar(F2_LastAccess, SizeOf(TFileTime), #0); 
    FillChar(F2_LastWrite, SizeOf(TFileTime), #0); 

    //Get file handles for the files in question 
    //Notice that even though we're using CreateFile 
    //the open disposition for the file is OPEN_EXISTING 
    F1 := CreateFile(PChar(F1), 0, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    F2 := CreateFile(PChar(F2), 0, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 

    //Get the file times for the files. 
    GetFileTime(F1, F1_CreateTime, F1_LastAccess, F1_LastWrite); 
    GetFileTime(F2, F2_CreateTime, F2_LastAccess, F2_LastWrite); 

    //Assign the function's result to comparison 
    //-1, File1 is younger than File2 
    //0, File1 is the same as File2 
    //+1 File1 is older than File2 
    Result := CompareFileTime(F1_CreateTime^, F2_CreateTime^); 

    //Free the memory allocated to the pointers 
    FreeMem(F1_CreateTime, SizeOf(TFileTime)); 
    FreeMem(F1_LastAccess, SizeOf(TFileTime)); 
    FreeMem(F1_LastWrite, SizeOf(TFileTime)); 
    FreeMem(F2_CreateTime, SizeOf(TFileTime)); 
    FreeMem(F2_LastAccess, SizeOf(TFileTime)); 
    FreeMem(F2_LastWrite, SizeOf(TFileTime)); 
end; 

任何幫助將不勝感激。

+0

提示:聲明TFileTime變量代替PFileTime變量,你不必GetMem和FreeMem(但當然FillChar)。 – 2010-08-16 04:51:58

+0

將聲明更改爲TFileTime,然後在CreateFile調用上出現編譯錯誤,因爲它期待PFileTime。 – TallGuy 2010-08-16 05:26:26

+0

@TallGuy:使用地址運算符「@」來傳入指針,例如'GetFileTime(F1,@ F1_CreateTime,@ F1_LastAccess,@ F1_LastWrite);' – 2010-08-16 05:45:32

回答

4

德爾福2010年已經包含一個簡單的包裝獲取UTC時間在ioutils.pas。這是一段比較文件的UTC創建時間的代碼。

uses 
    IOUtils, DateUtils; 

function CompareFileCreationTimeUtc(const aFile1, aFile2: String): integer; 
var 
    lCreationTime1: TDateTime; 
    lCreationTime2: TDateTime; 
begin 

    lCreationTime1 := TFile.GetCreationTimeUtc(aFile1); 
    lCreationTime2 := TFile.GetCreationTimeUtc(aFile2); 

    Result := CompareDateTime(lCreationTime1, lCreationTime2); 

end; 
+0

謝謝,這個工作很完美 – TallGuy 2010-08-16 21:23:59

1

如果你不想使用IOUtils常規,喜歡自己做,你的函數應該予以糾正像(未經測試):

function CompareFileTimes(File1, File2 : String) : LongInt; 
var 
    F1, F2: THandle; 
    F1_CreateTime, F2_CreateTime: TFileTime; 
begin 
    //Fill the structures with nulls for now 
    ZeroMemory(@F1_CreateTime, SizeOf(TFileTime)); 
    ZeroMemory(@F2_CreateTime, SizeOf(TFileTime)); 

    //Get file handles for the files in question 
    //Notice that even though we're using CreateFile 
    //the open disposition for the file is OPEN_EXISTING 
    F1 := CreateFile(PChar(File1), 0, FILE_SHARE_READ , nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    F2 := CreateFile(PChar(File2), 0, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 

    if (F1=INVALID_HANDLE_VALUE) or (F1=INVALID_HANDLE_VALUE) then 
    RaiseLastOSError; 

    //Get the file times for the files. 
    if not GetFileTime(F1, @F1_CreateTime, nil, nil) or 
    not GetFileTime(F2, @F2_CreateTime, nil, nil) then 
    RaiseLastOSError; 
    //Assign the function's result to comparison 
    //-1, File1 is younger than File2 
    //0, File1 is the same as File2 
    //+1 File1 is older than File2 
    Result := CompareFileTime(F1_CreateTime, F2_CreateTime); 
end; 
+0

謝謝,這也按預期工作。 – TallGuy 2010-08-16 21:24:56