16.2.3. Работа с датой создания файлов
Работа с датой создания файлов — в общем-то, не первая необходимость. Но для написания антивирусных программ, для ведения картотек и баз данных или анализа файлов данных — это «рабочий» инструмент.
Для работы с файлами в модуле DOS вводится предопределенный тип с именем DateTime. Это запись со структурой
TYPE
DateTime = RECORD
Year, Month, Day, Hour, Min, Sec : Word;
END;
- 353 -
Поля этой записи представляют собой нормальные значения даты и времени, с ограничением лишь на диапазон возможных значений: 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
- 354 -
| 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 на различных ПЭВМ.