Системное программирование в 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 для получения размера открытого файла, не изменяя при этом значения указателя чтения-записи.




Содержание  Назад  Вперед