Системное программирование в UNIX средствами Free Pascal

       

это дескриптор открытого файла. Второй


uses linux;
Function fdSeek(filedes, offset, SeekType:longint):longint;
Первый параметр, filedes, – это дескриптор открытого файла. Второй параметр, offset, обычно определяет новое положение указателя чтения-записи и задает число байтов, которое нужно добавить к начальному положению указателя. Третий целочисленный параметр, SeekType, определяет, что принимается в качестве начального положения, то есть откуда вычисляется смещение offset. Флаг SeekType может принимать одно из символьных значений (определенных в модуле linux), как показано ниже:

SEEK_SET
Смещение offset вычисляется от начала файла, обычно имеет значение = 0


SEEK_CUR
Смещение offset вычисляется от текущего положения в файле, обычное значение = 1
SEEK_END
Смещение offset вычисляется от конца файла, обычное значение = 2

Эти значения показаны в графическом виде на рис. 2.1, на котором представлен файл из 7 байт.

<
SEEK_SET
a
Текущее
b
положение
>
c
<
SEEK_CUR
указателя
d
файла
e
f
g
<
SEEK_END

Рис. 2.1. Символьные значения флага SeekType
Пример использования вызова fdseek:
var
  newpos:longint;
.
.
.
newpos := fdseek(fd, -16, SEEK_END);
который задает положение указателя в 16 байтах от конца файла.
Во всех случаях возвращаемое значение (содержащееся в переменной newpos в примере) дает новое положение в файле. В случае ошибки оно будет содержать стандартный код ошибки -1.
Существует ряд моментов, которые следует отметить. Во-первых, обе переменные newpos и offset имеют тип longint, и должны вмещать смещение для любого файла в системе. Во-вторых, как показано в примере, смещение offset может быть отрицательным. Другими словами, возможно перемещение в обратную сторону от начального положения, заданного флагом SeekType. Ошибка возникнет только при попытке переместиться при этом на позицию, находящуюся до начала файла. В-третьих, можно задать позицию за концом файла. В этом случае, очевидно, не существует данных, которые можно было бы прочитать – невозможно предугадать будущие записи в этот участок (UNIX не имеет машины времени) – но последующий вызов fdwrite имеет смысл и приведет к увеличению размера файла. Пустое пространство между старым концом файла и начальным положением новых данных не обязательно выделяется физически, но для последующих вызовов fdread оно будет выглядеть как заполненное символами null ASCII.
В качестве простого примера мы можем создать фрагмент программы, который будет дописывать данные в конец существующего файла, открывая файл, перемещаясь на его конец при помощи вызова fdseek и начиная запись:
filedes := fdopen(filename, Open_RDWR);
fdseek(filedes, 0, SEEK_END);
fdwrite(filedes, outbuf, OBSIZE);
Здесь параметр направления поиска для вызова fdseek установлен равным SEEK_END для перемещения в конец файла. Так как перемещаться дальше нам не нужно, то смещение задано равным нулю.
Вызов fdseek также может использоваться для получения размера файла, так как он возвращает новое положение в файле.
var
  filesize:longint;
  filedes:integer;
.
.
.
filesize := fdseek(filedes, 0, SEEK_END);
Упражнение 2.8. Напишите функцию, которая использует вызов fdseek для получения размера открытого файла, не изменяя при этом значения указателя чтения-записи.

Содержание раздела