Private : Array [1..26] of Byte;

UserData : Array [1..16] of Byte;

Name : Array [0..79] of Char;

END;

Поле Handle содержит специальную информацию для файловых функций MS-DOS. Поле Mode типа Word хранит специальное число, характеризующее состояние файла. Для работы с этим полем определены четыре константы (и только их значения могут содержаться в этом поле):

CONST

fmClosed = $D7B0; { файл закрыт }

fmInput = $0781; { текстовый файл открыт для чтения }

fmOutput = $D782; { текстовый файл открыт для записи }

fmInOut - $D7B3; { нетекстовый файл открыт для доступа }

{Все прочие значения говорят, что файл ни с чем не связан. }

Сравнивая значения констант со значением поля Mode, можно определить текущий статус файла.

Следующее поле записи FileRec — RecSize — содержит длину записи файла (она определяется типом компонентов файла). Для бестиповых файлов она устанавливается процедурами Rewrite или Reset, а для текстовых — процедурой SetTextBuf.

Поле Private, состоящее из 26 байт, зарезервировано и не используется, зато поле UserData может содержать практически любую информацию размером до 16 байт. Оно играет роль комментария к файлу. Здесь уместно напомнить, что основное назначение типа FileRec — обслуживание внутренних процессов языка. Из полей можно извлекать информацию, но запись в них может привести к непредсказуемым, а то и фатальным последствиям. (Исключение составляет процесс написания собственных драйверов текстовых файлов, что требует весьма высокой квалификации и знания «внутренностей» MS-DOS.) Поле UserData — единственное безопасное в этом плане.

Последний компонент записи FileRec — поле Name, которое содержит полное имя физического файла на диске. Заметим, что тип

- 359 -

имени не соответствует типу строки, и вдобавок к этому имя заканчивается символом #0.

Все сказанное выше относилось к нетекстовым файлам. Для текстовых файлов используется запись с другой структурой:

TYPE

TextBuf = Array[0..127] of Char; { стандартный буфер }

TextRec = RECORD

Handle : Word;

Mode : Word; { состояние файла fmXXX }

BufSize : Word; { размер буфера }

Private : Word;

BufPos : Word;

BufEnd : Word;

BufPtr : ^TextBuf; { адрес буфера в памяти }

OpenFunc : Pointer; { адреса драйверов: }

InOutFunc: Pointer;

FlushFunc: Pointer;

CloseFunc: Pointer;

UserData : Array [1..16] of Byte;

Name : Array [0..79] of Char;

Buffer : TextBuf;

END;

Первые поля имеют тот же смысл, что и для нетекстовых файлов. Поле Mode может содержать те же значения констант. Дополнительные поля отведены для работы с текстовым буфером, а группа полей типа Pointer содержит адреса функций — драйверов текстовых файлов. Если в них не записаны адреса своих текстовых драйверов, то принимаются системные.

Кроме случаев создания собственных драйверов, следует избегать внесения изменений в поля записи (кроме поля UserData). Это требование остается и для текстовых файлов.

Если кого-либо заинтересовала возможность использования системной информации о файлах, то обязательно появится вопрос: а как к ней добраться? Ни одна функция или процедура языка не имеет аргумента типа FileRec или TextRec. Создание переменной таких типов будет пустой тратой памяти. Оказывается, что это и не нужно. Для работы с файлами необходимо объявлять их переменные, например:

VAR

tf : Text; { текстовый файл }

fr : File of Real; { файл вещественных чисел }

f : File; { бестиповый файл }

- 360 -

Предопределено, что структура типа File и File of... соответствует типу FileRec (размер 128 байт), а типа Text — типу TextRec (paзмер 256 байт). Используя операцию преобразования типов, легко опросить любое поле системного типа. Примеры этого:

if TextRec( tf ).Mode = fmOutput then ... ;

if FileRec( fr ).Mode <> fmlnOut then ... ;

ByteVAR := FileRec( f ).UserData[4];

и т.п. Пример извлечения имени файла из записи:

StringVAR := ' '; i := 0; { имя файла }

repeat

StringVAR := StringVAR + TextRec( tf ).Name[i];

Inc( i )

until StringVAR[i]=#0;

...

Работая таким образом с файловыми переменными, следует всегда помнить, что файловая переменная f перед анализом обязательно должна «пройти» через процедуры Assign (f, имя физического файла) и Reset или Rewrite. В противном случае поля типов будут содержать в буквальном смысле что угодно, кроме полезной информации.

Возможное применение описанных записей — анализ состояния конкретных файлов через поле Mode, добавление комментариев в поле UserData. Это достаточно полезно и относительно несложно. Но основное их назначение — подключение собственных файловых драйверов. Этот вопрос слишком сложен и в этой книге не рассматривается.

Зато все вышеизложенное можно с пользой применять при отладке программ в среде Турбо Паскаль. Если, например, непонятно, что творится с логическим текстовым файлом MyFile, то можно поместить его в окно отладчика Watch в преобразованном виде:

TextRec( MyFile ), R

И при трассировке поля записи будут заполняться внутренними параметрами. Подобный фокус можно провести и с окном опроса Evaluate.

Перейти на страницу:

Поиск

Похожие книги