12.9. Последовательный и прямой доступ к файлам

Файл — это последовательная структура данных. И естественным способом доступа к компонентам файла является последовательный доступ. После открытия файла он «ждет» чтения или записи первого компонента. После каждого очередного обращения к файлу он готов выдать или принять очередной по счету компонент. В данном случае возможно только косвенно управлять последовательностью чтения или записи.

Пусть нужно прочитать из файла f пятый элемент и записать его в переменную V соответствующего типа. Это можно сделать, считав «впустую» четыре первых значения:

Reset( f ); { файл открыт для чтения первого компонента }

for i:=1 to 5 do Read ( f, v );

Reset(f); { переустановка снова на первый компонент }

В V останется лишь последнее, пятое, значение из файла. Это, конечно, не самое удачное решение проблемы прямого доступа, т.е. доступа сразу к тому компоненту, который нас интересует. Гораздо лучше будет использовать встроенные процедуры и функции Турбо Паскаля для прямого доступа к компонентам файла (табл. 12.4).

- 255 -

Функции и процедуры

Назначение

FileSize(VAR : f) : LongInt

Возвращает число записей компонентов или блоков в открытом файле f

FilePos(VAR f) : LongInt

Функция возвращает номер записи компонента или блока в открытом файле f, предшествующий тому, который будет считан или записан последующей операцией ввода-вывода

Seek(VAR f; W : LongInt)

Устанавливает текущим компонентом (блоком) в открытом файле f компонент с номером N, отсчитанным от нулевого. Назначенный компонент будет считан или записан последующей операцией ввода-вывода

Truncate(VAR f)

Отсекает часть открытого файла f, начиная с того компонента, который был бы считан последующей операцией ввода, и подтягивает на ее место конец файла

Внимание! Процедуры и функции прямого доступа применимы только к типизированным и бестиповым файлам, но не к текстовым.

В эту же таблицу можно было бы включить и функцию EOF(VAR f), описанную ранее в этой главе как общую для всех файлов.

Прямой доступ означает возможность позиционировать внутри файла указатель на интересующую нас запись. В случае типизированных файлов запись в файле — это компонент файла, а в случае бестиповых — блок, равный по размеру буферу файла. Далее в этом разделе мы будем использовать термин «запись» именно в этом смысле (ранее мы избегали его из-за двусмысленности: запись компонента в файле сама может быть записью (record) в смысле типа данных).

Файл заполняется последовательно от начала. Его структура всегда линейна: запись следует за записью. В нем не может быть «дыр». Добавить запись можно лишь в конец, удлинив тем самым сплошную их цепочку в файле. Правда, можно заместить любую

- 256 -

существующую в файле запись, но это не изменит его структуры и длины.

Для индексации структуры файла достаточно просто пронумеровать его записи, что и делается в Турбо Паскале. Но эта нумерация достаточно своеобразна. Можно считать, что нумеруются не записи, а как бы границы между ними (рис. 12.8). Эти границы — чистая условность, и в реальном файле записи не разделяются, а идут подряд. Просто они позволяют наглядно изобразить принцип нумерации записей. Самая первая граница (в начале файла) имеет номер 0.

Рис. 12.8

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