FileGetDate()
Delphi 5 での実装は次のとおりです。
function FileGetDate(Handle: Integer): Integer;
var
FileTime, LocalFileTime: TFileTime;
begin
if GetFileTime(THandle(Handle), nil, nil, @FileTime) and
FileTimeToLocalFileTime(FileTime, LocalFileTime) and
FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi,
LongRec(Result).Lo) then Exit;
Result := -1;
end;
これは、任意の入力ファイル ハンドルで発生する可能性のある3 つの異なる障害点です。
GetFileTime()
失敗しますか?
FileTimeToLocalFileTime()
失敗しますか?
FileTimeToDosDateTime()
失敗しますか?
失敗しない限りFileOpen()
(チェックしていません--1
ファイルを開くことができない場合に返されます)、#1または#2が失敗することはほとんどありません(不可能ではありません)。ただし、#3 には文書化された警告があります。
MS-DOS の日付形式は、1980 年 1 月 1 日から 2107 年 12 月 31 日までの日付のみを表すことができます。入力ファイルの時間がこの範囲外の場合、この変換は失敗します。
タイムスタンプが 2108 年以降のファイルに遭遇する可能性は低いですが、タイムスタンプが 1979 年以前のファイルに遭遇する可能性は確かにあります。
CreateFile()
4 つのすべての関数 (内で呼び出される関数を数えますFileOpen()
) は、 を介してエラー コードを報告するGetLastError()
ため、次のように実行できます。
var
Src : integer;
FileDate : LongInt;
begin
Src := FileOpen(SrcPath, fmOpenRead);
Win32Check(Src <> -1);
FileDate := FileGetDate(Src);
Win32Check(FileDate <> -1);
...
Win32Check(FileSetDate(Dest, FileDate) = 0);
Win32Check()
RaiseLastWin32Error()
入力パラメーターが false の場合に呼び出します。プロパティに実際のエラー コードを含む例外を発生させRaiseLastWin32Error()
ます。EOSError
ErrorCode
失敗した場合FileGetDate()
、どの Win32 関数が実際に失敗したかは明らかにわかりません。そこでデバッガの出番です。Project Options で Debug DCUs を有効にして、VCL/RTL ソース コードにステップインできるようにします。失敗したファイルを見つけて FileGetDate() を呼び出し、そのソース コードをステップ実行して、3 つの API 関数が実際に失敗しているかどうかを確認します。
についても同様でFileSetDate()
、これも 3 つの API 関数を内部的に呼び出します。
function FileSetDate(Handle: Integer; Age: Integer): Integer;
var
LocalFileTime, FileTime: TFileTime;
begin
Result := 0;
if DosDateTimeToFileTime(LongRec(Age).Hi, LongRec(Age).Lo, LocalFileTime) and
LocalFileTimeToFileTime(LocalFileTime, FileTime) and
SetFileTime(Handle, nil, nil, @FileTime) then Exit;
Result := GetLastError;
end;
FileSetDate()
失敗した場合、それは次の理由によるものですか。
DosDateTimeToFileTime()
失敗した?
LocalFileTimeToFileTime()
失敗した?
SetFileTime()
失敗しましたか?