Delphi - Datele fisierelor sau directoarelor

Delphi - Datele fisierelor sau directoarelor

Postby v0id » 23 Jan 2010, 18:29

De cele mai multe multe ori cand am avut nevoie de proprietatile unui fisier sau ale unui director, am avut nevoie si de data crearii, data ultimei modificari si data ultimului acces facut pe fisier.

In acest caz insa uneori trebuie tinut cont de faptul ca folosind de exemplu TSearchRec.Time din Delphi pentru a obtine data ultimei modificari, se ia automat in calcul Time Zone-ul sistemului impreuna cu Daylight Saving Time. Astfel daca avem un fisier a carui data a ultimei modificari in format UTC este 01.01.2010 15:30:00 si suntem pe Time Zone +2, folosind TSearchRec.Time vom avea 01.01.2010 17:30:00. Peste asta mai intervine si Daylight Saving Time, care pe Time Zone-ul nostru influenteaza aceasta data cu o ora in plus vara, deci vom avea 01.01.2010 18:30:00.

Uneori avem nevoie de datele "reale" ale fisierului, adica cele in format UTC, neinfluentate de Time Zone si Daylight Saving Time. Astfel am conceput o functie care imi permite sa iau cele trei date ale unui fisier sau director (creare, modificare, acces) asa cum am nevoie - cu sau fara Time Zone si Daylight Saving Time. Functia se numeste GetFileTimes si o aveti mai jos. Aceasta functie se bazeaza pe cateva conversii intre diferite formate de data folosite in Delphi si pentru usurinta, acele conversii le-am mutat intr-o alta functie, GetDTFromFileTime, apelata de catre GetFileTimes pentru fiecare dintre cele trei date ale fisierului sau directorului.

Parametri GetFileTimes:
aPath - calea catre fisier sau director
aCreate, aModif, aAccess - parametrii in care se vor returna: data crearii, data ultimei modificari, data ultimului acces pe fisier
aWithTimeZone - daca este True se va tine cont de Time Zone si Daylight Saving Time; daca este False nu se va tine cont de cei doi factori si se vor returna datele in format UTC

Rezultat GetFileTimes:
True - operatie efectuata cu succes
False - fisierul nu a putut fi deschis sau s-a intalnit o exceptie

  1.  
  2. function GetDTFromFileTime(aFileTime: TFileTime; aWithTimeZone: boolean): TDateTime;
  3. var
  4.   lFileTime: TFileTime;
  5.   lSystemTime: TSystemTime;
  6.   lDateTime: TDateTime;
  7. begin
  8.   Result := 0;
  9.  
  10.   // Verificam daca conversia din TFileTime in TDateTime trebuie sa tina cont de Time Zone si Daylight Saving Time
  11.   // si facem conversia in TSystemTime
  12.   if aWithTimeZone then
  13.     begin
  14.       FileTimeToLocalFileTime(aFileTime, lFileTime);
  15.       FileTimeToSystemTime(lFileTime, lSystemTime);
  16.     end
  17.    else
  18.     FileTimeToSystemTime(aFileTime, lSystemTime);
  19.  
  20.    // Conversie din TSystemTime in TDateTime si returnare rezultat
  21.    lDateTime := EncodeDate(lSystemTime.wYear, lSystemTime.wMonth, lSystemTime.wDay);
  22.    Result := lDateTime + EncodeTime(lSystemTime.wHour, lSystemTime.wMinute, lSystemTime.wSecond, lSystemTime.wMilliSeconds);
  23.    if (Result <> SystemTimeToDateTime(lSystemTime)) then
  24.      Result := SystemTimeToDateTime(lSystemTime);
  25. end;
  26.  
  27. function GetFileTimes(aPath: string; var aCreate, aModif, aAccess: TDateTime; aWithTimeZone: boolean): boolean;
  28. var
  29.   lFileHandle: integer;
  30.   FTimeC, FTimeA, FTimeM: TFileTime;
  31. begin
  32.   Result := False;
  33.  
  34.   aCreate := 0;
  35.   aModif := 0;
  36.   aAccess := 0;
  37.  
  38.   try
  39.     // Deschidere fiser/director
  40.     lFileHandle := Integer(CreateFile(PChar(aPath), GENERIC_READ,
  41.                            FILE_SHARE_READ, nil, OPEN_EXISTING,
  42.                            FILE_ATTRIBUTE_NORMAL or FILE_FLAG_BACKUP_SEMANTICS, 0));
  43.  
  44.     // Verificare daca fisierul/directorul a putut fi accesat
  45.     if (lFileHandle <> 0) and (lFileHandle <> INVALID_HANDLE_VALUE) then
  46.       begin
  47.         // Preluare date in ca TFileTime
  48.         GetFileTime(lFileHandle, @FTimeC, @FTimeA, @FTimeM);
  49.         // Inchidere fisier
  50.         FileClose(lFileHandle);
  51.  
  52.         // Conversie date fisier in TDateTime
  53.         aCreate := GetDTFromFileTime(FTimeC, aWithTimeZone);
  54.         aAccess := GetDTFromFileTime(FTimeA, aWithTimeZone);
  55.         aModif := GetDTFromFileTime(FTimeM, aWithTimeZone);
  56.  
  57.         Result := True;
  58.       end;
  59.   except
  60.     Result := False;
  61.   end;
  62. end;
  63.  


Pentru a vedea diferentele despre care vorbeam mai sus, folositi urmatoarea bucata de cod (Ignorati diferenta de max. 2 secunde care poate sa apara la unele fisiere sau directoare. Mai multe informatii aici):

  1.  
  2. procedure TForm1.Button1Click(Sender: TObject);
  3. var
  4.   lCreate, lModif, lAccess: TDateTime;
  5.   lSearchRec: TSearchRec;
  6. begin
  7.   GetFileTimes('CALE FISIER SAU DIRECTOR', lCreate, lModif, lAccess, False);
  8.  
  9.   if (FindFirst('CALE FISIER SAU DIRECTOR', faAnyFile, lSearchRec) = 0) then
  10.     begin
  11.       ShowMessage(// Data ultimei modificari returnata de functia GetFileTimes
  12.                   'Modif GetFileTimes: ' + DateTimeToStr(lModif) + '; ' +
  13.                  
  14.                   // Data ultimei modificari returnata de TSearchRec.Time
  15.                   'Modif TSearchRec.Time: ' + DateTimeToStr(FileDateToDateTime(lSearchRec.Time))
  16.                  );
  17.     end;
  18. end;
  19.  

2 points / 2 votes
A good coder is never on holiday - he may be working on a different machine, that's about as far as it gets.
User avatar
v0id
Byte
 
Joined: 05 Jan 2010
Location: 127.0.0.1
Points: 19

Return to Snippets

Who is online

Users browsing this forum: No registered users and 0 guests