16.4.1. Типы и константы модуля DOS для работы с файлами

We use cookies. Read the Privacy and Cookie Policy

Для обеспечения работы процедур первых двух групп в модуле DOS вводятся специальные типы и константы. Так, для ввода атрибутов файла или их анализа определены константы

CONST

ReadOnly = $01; { только для чтения }

Hidden = $02; { скрытый файл }

SysFile = $04; { системный (непереносимый) }

VolumeID = $08; { метка диска }

Directory = $10; { подкаталог }

Archive = $20; { архивный (для BACKUP) }

AnyFile = $3F; { сумма всех предыдущих }

При использовании их можно складывать. Так, имя файла имеет шестнадцать вариантов композиций атрибутов ReadOnly, Hidden, SysFile, Archive; имя подкаталога может быть скрытым и т.п. Не стоит только суммировать что-либо с константой AnyFile, ибо она уже есть сумма всех предыдущих.

Для процедур FindFirst и FindNext введен тип SearchRec:

TYPE

SearchRec = RECORD

Fill : Array[1..21] of Byte; {системное поле }

Attr : Byte; {поле атрибута }

Time : LongInt; {запись времени }

Size : Longlnt; {размер файла }

Name : String[12]; {имя файла }

END;

Поля переменной этого типа содержат информацию по последнему найденному имени файла или подкаталога. Кроме того, предопределены еще две записи для поддержания работы с файлами. Для всех

- 358 -

файлов (типизированных или бестиповых), кроме текстовых, имеется системный тип:

TYPE

FileRec = RECORD

Handle : Word;

Mode : Word;

RecSize : Word;

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.

Для третьей группы (процедуры FSplit и функции FExpand) вводятся специальные типы для ведения имен файлов и подкаталогов:

- 361 -

TYPE

ComStr = String [127]; { для командной строки }

PathStr = String [79]; { для полного имени файла }

DirStr = String [67]; { для маршрута на диске }

NameStr = String [8]; { только имя файла }

ExtStr = String [4]; { точка и расширение }

Для работы с процедурами поисков файлов и анализа имен необходимо вводить переменные именно таких типов. Размеры строк в типах соответствуют ограничениям MS-DOS на длину имен и маршрутов.

Для работы с файлами может также пригодиться системная переменная модуля DOS — DosError.