Книга: Разработка приложений в среде Linux. Второе издание

13.4.2. Игнорирование указателя файла

13.4.2. Игнорирование указателя файла

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

lseek(fd, SEEK_SET, offset1);
read(fd, buffer, bufferSize);
offset2 = someOperation(buffer);
lseek(fd, SEEK_SET, offset2);
read(fd, buffer2, bufferSize2);
offset3 = someOperation(buffer2);
lseek(fd, SEEK_SET, offset3);
read(fd, buffer3, bufferSize3);

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

#define XOPEN_SOURCE 500
#include <unistd.h>
size_tpread(int fd, void * buf, size_t count, off_t offset);
size_t pwrite(int fd, void * buf, size_t count, off_t offset);
#endif

Это выглядит подобно прототипам read() и write() с четвертым параметром, offset. offset определяет, с какой точки файла следует читать, а в какую — записывать. Как и их "тезки", эти функции возвращают количество переданных байтов. Ниже приведена версия pread(), реализованная с помощью read() и lseek(), что облегчает понимание ее функции[99].

int pread (int fd, void * data, int size, int offset) {
 int oldOffset;
 int rc;
 int oldErrno;
 /* переместить указатель файла в новое расположение */
 oldOffset = lseek(fd, SEEK_SET, offset);
 if (oldOffset < 0) return -1;
 rc = read(fd, data, size);
 /* восстановить указатель файла, предварительно сохранив errno */
 oldErrno = errno;
 lseek(fd, SEEK_SET, oldOffset);
 errno = oldErrno;
 return rc;
}

Оглавление книги


Генерация: 1.397. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз