Работа с датой создания файлов — в общем-то, не первая необходимость. Но для написания антивирусных программ, для ведения картотек и баз данных или анализа файлов данных — это «рабочий» инструмент.
Для работы с файлами в модуле DOS вводится предопределенный тип с именем DateTime. Это запись со структурой
TYPE
DateTime = RECORD
Year, Month, Day, Hour, Min, Sec : Word;
END; {352}
Поля этой записи представляют собой нормальные значения даты и времени, с ограничением лишь на диапазон возможных значений: Year имеет диапазон 1980...2099, Month — 1...12, Day — 1...31, Hour — 0...23, Min и Sec — 0...59.
В MS-DOS вся эта информация упакована в четыре байта, что соответствует типу LongInt Турбо Паскаля. Для преобразования даты и времени в формат MS-DOS служит процедура
PackTime( VAR DT : DateTime; VAR Т : LongInt )
Для обратного кодирования из LongInt в DateTime служит процедура
UnPackTime ( Т : LongInt; VAR DT : DateTime )
Но обе эти процедуры имеют смысл только в сопряжении с процедурами чтения и записи времени создания файла:
GetFTime( VAR f; VAR Т : LongInt )
и
SetFTime( VAR f; Т : LongInt )
Переменная f в них обозначает файл произвольного типа, вернее его логическое имя. Этот файл к моменту вызова процедур GetTime/SetTime должен быть связан с каким-либо физическим файлом на диске и открыт для записи или чтения. Переменная T в первом случае возвращает упакованные дату и время, во втором — содержит и устанавливает их. Сказанное можно проиллюстрировать программой чтения и установки даты создания файлов (рис. 16.5).
{ ПРИМЕР СМЕНЫ ДАТЫ СОЗДАНИЯ ФАЙЛА }
USES DOS;
{ Процедура назначает файлу Fname дату и время NewDT. }
PROCEDURE ChangeFtime(Fname: String; NewDT: DateTime);
VAR
f : File; { переменная для любого файла }
ftime : LongInt; { переменная для Get/SetFTime }
dt : DateTime; { переменная для Pack/UnpackTime }
BEGIN
Assign( f, Fname); { связь f с файлом }
{$I-} Reset( f ); {$I+} { попытка открытия файла}
if IOResult<>0 then Exit; { выход, если файла нет }
GetFTime( f, ftime); { считывание времени }
UnpackTime( ftime, dt ); { расшифровка времени }
Рис. 16.5 {353}
with dt do
WriteLn("Дата и время создания файла '+Fname+' : ',
Day :1, '-', Month:1, '-‘, Year:1, ' ‘,
Hour:1, ':', Min :1, ':', Sec :1 );
PackTime( NewDT, ftime ); { упаковка новой даты }
SetFTime( f, ftime ); { назначение ее файлу }
Close( f ); { закрытие файла }
with NewDT do
WriteLn('Новые дата и время создания файла : ',
Day :1, '-', Month:1, '-', Year:1, ' ',
Hour:1, ':', Min :1, ':', Sec :1 );
END; { ChangeFTime }
{ -- ПРИМЕР ВЫЗОВА ПРОЦЕДУРЫ -- }
CONST
NewDT : DateTime = ( Year:1991; Month:1; Day:1;
Hour:5; Min:5; Sec:0 );
BEGIN
ChangeFTime( 'TEST.PAS', NewDT );
ReadLn { пауза до нажатия клавиши ввода }
END.
Рис. 16.5 (окончание)
Процедура GetFTime работает с файлами, открытыми как для записи ( через Rewrite или Append ), так и для чтения (Reset). Однако процедуру SetFTime следует применять только к файлам, открытым для чтения. В противном случае процедура закрытия файла Close переустановит значение времени и даты на текущее системное. Чтобы избежать этого, можно вставить перед вызовом SetFTime оператор Reset, переоткрывающий этот же файл, но уже для чтения. Дальнейшая запись в него будет, правда, невозможна, но все это можно проделать непосредственно перед закрытием файла, и проблемы не будет.
При тестировании демонстрационной программы мы заметили необычный эффект (Турбо Паскаль 5.5, MS-DOS 3.30, PS/2-50): при назначении файлу времени 0 ч 0 мин 0 с MS-DOS переставала выдавать время создания файлов при подаче команды DIR. Возможно, этот эффект будет сохраняться в различных версиях DOS на различных ПЭВМ.