Главная » Программирование для UNIX » Произвольный доступ – Iseek

0

Обычно  ввод-вывод выполняется  последовательно: каждая операция чтения или записи начинается там, где закончилась предыдущая. Но при необходимости файл может быть прочитан и записан в произвольном порядке. Системный вызов lseek позволяет перемещаться по фай лу, не выполняя при этом чтение или запись:

int fd, origin;

long  offset,  pos,  lseek();

pos  = lseek(fd, offset,  origin);

В этом фрагменте текущая позиция в файле с дескриптором fd перемещается на  offset байт относительно позиции, определенной параметром  origin. Следующая операция чтения или записи начнется с этой позиции. Параметр origin может принимать значения 0, 1 и 2, при этом смещение отсчитывается от начала файла,  от текущей позиции и от конца файла соответственно. Функция возвращает новое значение абсолютной позиции или –1 в случае ошибки. Например, чтобы дописать данные в файл, переместитесь в его конец:

lseek(fd, 0L,  2);

Чтобы вернуться в начало («перемотать»),

lseek(fd, 0L,  0);

Чтобы определить текущую позицию,

pos  = lseek(fd, 0L,  1);

Обратите внимание  на  аргумент 0L: смещение – это  длинное целое. (Буква «l»  в имени lseek означает long, т. е. «длинное», что отличает эту  функцию от seek  из  шестой версии,  использующей короткие целые.)

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

get(fd, pos,  buf, n)  /*  прочитать  n байт из позиции pos  */ int  fd, n;

long  pos; char  *buf;

{

if (lseek(fd, pos,  0)  == –1)  /*  перейти на позицию  pos  */ return –1;

else

return read(fd, buf, n);

Упражнение 7.3. Измените функцию readslow так, чтобы она обрабатывала  имя  файла, если оно передано параметром. Добавьте параметр –e:

$ readslow  -e

заставляющий readslow  перемещаться в конец  входного файла перед  началом чтения. Как поведет себя  lseek при работе с программным каналом (pipe)? ~

Упражнение 7.4.  Перепишите функцию efopen из главы 6 с использованием вызова error. ~

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии