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;
}
Больше книг — больше знаний!
Заберите 20% скидку на все книги Литрес с нашим промокодом
ПОЛУЧИТЬ СКИДКУ