Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Какие есть еще функции типа FileAge?


Автор: Etar 16.7.2009, 07:44
Нужно получить время изменения файла по его имени в формате FileDate, но функция FileAge оказывается уже устарела в D2009. Есть еще FileGetDate, но там нужно сперва файл открывать или создавать.
Есть какие-нибудь функции, которые на лету выхватывают из файла дату? (или в них тоже сперва открытие файла происходит?)

Автор: CodeMonkey 16.7.2009, 09:39
Вообще-то, http://transl-gunsmoker.blogspot.com/2008/11/blog-post_24.html.

Из JCL (как видим: ничего сложного):

Код
interface

...

function GetFileInformation(const FileName: string; out FileInfo: TSearchRec): Boolean; overload;
function GetFileInformation(const FileName: string): TSearchRec; overload;

function GetFileCreation(const FileName: string): TFileTime; overload;
function GetFileCreation(const FileName: string; out LocalTime: TDateTime): Boolean; overload;
function GetFileLastWrite(const FileName: string): TFileTime; overload;
function GetFileLastWrite(const FileName: string; out LocalTime: TDateTime): Boolean; overload;
function GetFileLastAccess(const FileName: string): TFileTime; overload;
function GetFileLastAccess(const FileName: string; out LocalTime: TDateTime): Boolean; overload;

implementation

...

function FileTimeToLocalDateTime(const FileTime: TFileTime): TDateTime;
begin
  // самостоятельно ;)
end;

...

function GetFileInformation(const FileName: string; out FileInfo: TSearchRec): Boolean; 
begin
  Result := FindFirst(FileName, faAnyFile, FileInfo) = 0;
  if Result then
    SysUtils.FindClose(FileInfo);
end;

function GetFileInformation(const FileName: string): TSearchRec;
begin
  if not GetFileInformation(FileName, Result) then
    RaiseLastOSError;
end;

function GetFileCreation(const FileName: string): TFileTime;
begin
  Result := GetFileInformation(FileName).FindData.ftCreationTime;
end;

function GetFileCreation(const FileName: string; out LocalTime: TDateTime): Boolean;
var
  FileInfo: TSearchRec;
begin
  Result := GetFileInformation(FileName, FileInfo);
  if Result then
    LocalTime := FileTimeToLocalDateTime(GetFileInformation(FileName).FindData.ftCreationTime);
end;

function GetFileLastWrite(const FileName: string): TFileTime;
begin
  Result := GetFileInformation(FileName).FindData.ftLastWriteTime;
end;

function GetFileLastWrite(const FileName: string; out LocalTime: TDateTime): Boolean;
var
  FileInfo: TSearchRec;
begin
  Result := GetFileInformation(FileName, FileInfo);
  if Result then
    LocalTime := FileTimeToLocalDateTime(GetFileInformation(FileName).FindData.ftLastWriteTime);
end;

function GetFileLastAccess(const FileName: string): TFileTime;
begin
  Result := GetFileInformation(FileName).FindData.ftLastAccessTime;
end;

function GetFileLastAccess(const FileName: string; out LocalTime: TDateTime): Boolean;
var
  FileInfo: TSearchRec;
begin
  Result := GetFileInformation(FileName, FileInfo);
  if Result then
    LocalTime := FileTimeToLocalDateTime(GetFileInformation(FileName).FindData.ftLastAccessTime);
end;

Автор: Romikgy 22.7.2009, 13:14
Цитата(CodeMonkey @  16.7.2009,  08:39 Найти цитируемый пост)
function FileTimeToLocalDateTime(const FileTime: TFileTime): TDateTime;
begin
  // самостоятельно ;)
end;

TimeStampToDateTime ...

Код

function FileAge(const FileName: string): Integer;
{$IFDEF MSWINDOWS}
var
  Handle: THandle;
  FindData: TWin32FindData;
  LocalFileTime: TFileTime;
begin
  Handle := FindFirstFile(PChar(FileName), FindData);
  if Handle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(Handle);
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    begin
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi,
        LongRec(Result).Lo) then Exit;
    end;
  end;
  Result := -1;
end;
{$ENDIF}

Автор: Riply 22.7.2009, 15:55
Цитата(CodeMonkey @  16.7.2009,  09:39 Найти цитируемый пост)
Из JCL (как видим: ничего сложного):


Сдается мне, что в FindFirstFileExW все же идет открытие файла через NtOpenFile в user mode.

Я бы попробовала через NtQueryAttributesFile.
Объект она скорее всего открывает уже в kernel mode и через ObOpenObjectByName.

Все это нуждается в проверке.
Т.к. автор хотел
Цитата(Etar @  16.7.2009,  07:44 Найти цитируемый пост)
Есть какие-нибудь функции, которые на лету выхватывают из файла дату? (или в них тоже сперва открытие файла происходит?) 

то ему с этой проверкой и карты в руки smile

Если лень лезть во внутренности, то можно просто в цикле повызывать данные ф-ии и сравнить время.
Не исключен вариант, что NtQueryAttributesFile хорошо обставит FindFirst smile 

P.S.
 Мне тож интересно кто быстрее smile

Автор: mrbrooks 22.7.2009, 16:02
Можно и так. Код из Билдера, но суть одна. 
Код

WIN32_FILE_ATTRIBUTE_DATA fad;
if (GetFileAttributesEx("c:\\file.txt", GetFileExInfoStandard,&fad))
{
 SYSTEMTIME st;
 FILETIME ft;
 FileTimeToLocalFileTime(&fad.ftLastWriteTime, &ft);
 FileTimeToSystemTime(&ft, &st);
 TDateTime dt = SystemTimeToDateTime(st);
 ShowMessage(dt.DateTimeString());
}



Etar, WIN32_FILE_ATTRIBUTE_DATA структура интересная. Рекомендую ее посмотреть в MSDN.

Автор: Quartz 6.8.2009, 16:06
Цитата(CodeMonkey @  16.7.2009,  09:39 Найти цитируемый пост)
Вообще-то, FileAge устарела ещё в Delphi 2.

Код

function FileAge(const FileName: string): Integer; overload; deprecated;
function FileAge(const FileName: string; out FileDateTime: TDateTime): Boolean; overload; // <=== OK

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)