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 на различных ПЭВМ.