Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PR_СП_лекции_укр.doc
Скачиваний:
6
Добавлен:
22.04.2019
Размер:
697.34 Кб
Скачать

2.4.2 Системні виклики pread і pwrite

pread — виконує читання з файлу, починаючи із заданої позиції

#include <unistd.h>

#include <sys/types.h>

ssize_t pread( int fd, void *buf, size_t nbytes,

off_t offset)

fd - дескриптор файлу

*buf адреса буфера для даних, що приймаються

nbytes - об'єм даних, що приймаються

offset - позиція у файлі;

Повертає кількість прочитаних байт або -1 у разі помилки (код помилки - в змінній errno)

pwrite — виконує запис у файл, в задану позицію

#include <unistd.h>

#include <sys/types.h>

ssize_t pwrite(int fd, void *buf, size_t nbytes, off_t offset)

fd - дескриптор файлу

*buf - адреса буфера з даними для запису

nbytes - кількість даних для запису

offset - позиція у файлі

Повертає кількість записаних байт або -1 у разі помилки (код помилки - в змінній errno)

Системні виклики pread і pwrite по своїй функціональності практично повністю співпадають з комбінацією виклику lseek і подальшим викликом read або write відповідно, за виключенням:

  • вони не користуються поточною позицією у файлі, оскільки позиція для запису або читання передається явно, через аргумент offset;

  • вони не змінюють поточну позицію у файлі. Фактично, поточна позиція повністю ігнорується цими викликами.

Для файлів, відкритих з прапором O_APPEND (див. розділ 2.8), поведінка pwrite повністю співпадає з поведінкою виклику write (аргумент offset ігнорується).

Зручність застосування одного виклику замість двох незаперечно, але, що важливіше, викликам pread і pwrite невластиві проблеми, пов'язані із зміною поточній позиції у файлі між lseek і подальшими викликами read або write з іншого процесу або потоку. Це може відбутися при використанні одного дескриптора декількома потоками додатку або при використанні дублікатів дескрипторів декількома процесами. То ж відноситься і до файлів, відкритих з прапором O_APPEND. Оскільки ні pread, ні pwrite не використовують покажчик поточної позиції у файлі, їм невластиві помилки пов'язані з невірним позиціонуванням.

2.4.3 Системні виклики readv і writev

readv — читання урозкид

#include <sys/uio.h>

#include <sys/types.h>

ssize_t readv(int fd, const struct iovec *iov,int iovcnt );

fd - дескриптор файлу

*iov - масив буферів для даних, що приймаються

iovcnt - кількість буферів

Повертає кількість прочитаних байт або -1 у разі помилки (код помилки - в змінній errno)

writev — запис із злиттям

#include <sys/uio.h>

#include <sys/types.h>

ssize_t writev(int fd, const struct iovec *iov, int iovcnt)

fd - дескриптор файлу

*iov - масив буферів з даними

iovcnt - кількість буферів

Повертає кількість записаних байт або -1 у разі помилки (код помилки - в змінній errno)

Виклики readv і writev дуже схожі на виклики read і write, але на відміну від останніх мають справу не з одним, а з декількома буферами. Іноді їх називають «читання урозкид» і «запис із злиттям». У файлі дані як і раніше розташовуються підряд, один за одним, але буфери можуть бути розкидані в пам'яті процесу.

Іншими словами, якщо вам необхідно записати у файл три структури, то замість трьох викликів write це можна зробити одним викликом writev, проте, поглянувши па другий аргумент, ви без зусиль зрозумієте — щоб використовувати ці виклики, доведеться трохи потрудитися, але чи коштують вони наших зусиль?

Перед викликом будь-якій з цих функцій, ви повинні створити масив iov (елементів iovcnt), в якому кожен елемент містить покажчик на буфер з даними і розмір буфера, по суті — другий і третій аргументи викликів read і write.

struct iovec — структура, використовувана в системних викликах rcadv і writev*

struct iovec {

void *iov_base; /* адреса буфера з даними */

size_t iov_len; /* розмір буфера */

}

У своїх програмах ви можете оголосити статичний масив з struct iovec а також розмістити його в динамічній пам'яті викликом malloc або іншим способом. Максимальне число елементів масиву для різних OС може декілька відрізнятися, але воно ніколи не буває менше 16. У OСL, що задовольняють специфікації SUS, ідентифікатор IOV_MAX відповідає максимальному числу елементів масиву. Якщо цей ідентифікатор не визначений, можна скористатися функцією sysconf з аргументом _.SC_IOV_MAX Але в більшості: реальних застосувань 16 елементів більш ніж достатньо.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]