NAME
pread, pwrite - 从给定的偏移量出读取或写入文件
SYNOPSIS
#include <unistd.h>
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
glibc的功能测试宏要求(请参阅feature_test_macros(7)):
pread(), pwrite():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
DESCRIPTION
pread() 从文件描述符fd中偏移量offset(从文件开头)处开始最多读取count字节数,
从buf开始将其计数到缓冲区中。 文件偏移量未更改。
pwrite() 从缓冲区buf读取offset字节写入文件描述符fd(偏移量offset处开始写入)。
文件偏移量未更改。
fd引用的文件必须是可定位的.
RETURN VALUE
成功后,pread()返回读取的字节数(返回零表示文件结束),而pwrite()返回
写入的字节数。
请注意,成功调用传输的字节数少于请求的字节数不是错误(请参见read(2)和write(2))
发生错误时,将返回-1并将errno设置为指示错误原因。
调用pread
相当于调用lseek
之后调用read
,调用pwrite
相当于调用lseek
之后调用write
。区别在于:
- 调用过程中,无法中断其定位或者进行其他的读/写操作
- 不更新当前文件偏移量
也就是说,pread()相当于:
off_t orig;
orig = lseek(fd, 0, SEEK_CUR); //保存当前offset
lseek(fd, offset, SEEK_SET);
s = read(fd, buf, len);
lseek(fd, orig, SEEK_SET); // 重置文件指针
对 pread()和 pwrite()而言,fd 所指代的文件必须是可定位的(即允许对文件描述符执行lseek()调用)。
这两个函数在多线程程序中很有用。
- 进程下辖的所有线程将共享同一文件描述符表。这也意味着每个已打开文件的文件偏移量为所有线程所共享。
- 当调用pread()或 pwrite()时,多个线程可同时对同一文件描述符执行 I/O 操作,且不会因其他线程修改文件偏移量而受到影响。
- 如果还试图使用 lseek()和 read()(或 write())来代替 pread()(或pwrite()),那么将引发竞争状态,这类似于O_APPEND 标志时的描述(当多个进程的文件描述符指向相同的打开文件句柄时,使用 pread()和 pwrite()系统调用同样能够避免进程间出现竞争状态)。