В качестве несколько надуманного, но возможно наглядного примера, предположим, что имеется файл residents, в котором записаны фамилии постояльцев гостиницы. Первая строка содержит фамилию жильца комнаты 1, вторая – жильца комнаты 2 и т.д. (очевидно, это гостиница с прекрасно организованной системой нумерации комнат). Длина каждой строки составляет ровно 41 символ, в первые 40 из которых записана фамилия жильца, а 41-й символ является символом перевода строки для того, чтобы файл можно было вывести на дисплей при помощи команды UNIX cat.
Следующая функция getoccupier вычисляет по заданному целому номеру комнаты положение первого байта фамилии жильца, затем перемещается в эту позицию и считывает данные. Она возвращает либо указатель на строку с фамилией жильца, либо нулевой указатель в случае ошибки (мы будем использовать для этого значение nil). Обратите внимание, что мы присвоили переменной дескриптора файла infile исходное значение –1. Благодаря этому мы можем гарантировать, что файл будет открыт всего один раз.
(* Функция getoccupier - получить фамилию из файла residents *)
uses linux;
const
NAMELENGTH=41;
var
namebuf:array [0..NAMELENGTH-1] of char; (* Буфер для фамилии *)
const
infile:integer=-1; (* Для хранения дескриптора файла *)
function getoccupier(roomno:integer):pchar;
var
offset, nread:longint;
begin
(* Убедиться, что файл открывается впервые *)
if infile = -1 then
begin
infile := fdopen ('residents', Open_RDWR);
if infile = -1 then
begin
getoccupier := nil; (* Невозможно открыть файл *)
exit;
end;
end;
offset := (roomno - 1) * NAMELENGTH;
(* Найти поле комнаты и считать фамилию жильца *)
if fdseek (infile, offset, SEEK_SET) = -1 then
begin
getoccupier := nil;
exit;
end;
nread := fdread (infile, namebuf, NAMELENGTH);
if nread <= 0 then
begin
getoccupier := nil;
exit;