read , readx , read64x, readv , readvx , eread , ereadv , Spread 或 preadv 子例程
用途
从文件中读取。
库
| 项 | 描述 |
|---|---|
| 读, 读, 读, Readvx, read64x, 传播, 普雷亚德夫 | 标准 C 库 (libc.a) |
| 埃雷阿德, 埃雷阿德 | MLS 库 (libmls.a) |
语法
#include <unistd.h> ssize_t read (FileDescriptor, Buffer, NBytes)
int FileDescriptor;
void * Buffer;
size_t NBytes; int readx (FileDescriptor, Buffer, NBytes, Extension)
int FileDescriptor;
char * Buffer;
unsigned int NBytes;
int Extension; int read64x (FileDescriptor, Buffer, NBytes, Extension)
int FileDescriptor;
void *Buffer;
size_t NBytes;
void *Extension;
ssize_t pread (int fildes, void *buf, size_t nbyte, off_t offset); #include <sys/uio.h> ssize_t readv (FileDescriptor, iov, iovCount)
int FileDescriptor;
const struct iovec * iov;
int iovCount; ssize_t readvx (FileDescriptor, iov, iovCount, Extension)
int FileDescriptor;
struct iovec *iov;
int iovCount;
int Extension; #include <unistd.h>
#include <sys/uio.h> ssize_t preadv (
int FileDescriptor,
const struct iovec * iov,
int iovCount,
offset_t offset); ssize_t eread (FileDescriptor, Buffer, Nbytes, labels)
int FileDescriptor;
const void * Buffer;
size_t NBytes;
sec_labels_t * labels;
ssize_t ereadv (FileDescriptor, iov, iovCount, labels)
int FileDescriptor;
const struct iovec * iov;
int iovCount;
sec_labels_t * labels;
描述
read 子例程尝试将与 FileDescriptor 参数关联的文件中的数据的 NBytes 读取到 Buffer 参数指向的缓冲区中。
readv 子例程执行相同的操作,但将输入数据分散到由 iov 参数指向的 iovec 结构数组指定的 iovCount 缓冲区中。 每个 伊奥韦茨 条目都指定内存中必须放置数据的区域的基本地址和长度。 读 子例程总是在进入下一个区域之前完全填充该区域。
读 和 Readvx 子例程分别与 读 和 读 子例程相同,但添加了 扩展 参数,这在从某些设备驱动程序进行读取以及读取目录时是必需的。 虽然可以直接读取目录,但可以改为使用 奥彭迪尔 和 Readdir 调用,因为它是一个更可移植的接口。
在能够查找的常规文件和设备上, read 从文件中与 FileDescriptor 参数相关联的文件指针给出的位置开始。 当从 读 子例程返回时,文件指针将以实际读取的字节数递增。
无法寻求始终从当前位置进行读取的设备。 未定义与此类文件关联的文件指针的值。
对于目录, readvx 子程序从与文件描述符参数关联的文件指针指定的位置开始。 此文件指针的值必须是 0 或文件指针在先前调用此目录上的 Readvx 子例程之后立即具有的值。 从 Readvx 子例程返回后,文件指针将递增一个与复制到缓冲区中的字节数不对应的数字。
当系统尝试从空管道 (先进先出 (FIFO)) 中进行读取时:
- 如果没有任何进程打开用于写入的管道,那么 读 将返回 0 以指示文件结束。
- 如果是某个进程,请打开管道以进行写入:
- 如果 O_NDELAY 和 O_NONBLOCK 处于清除状态 (缺省值) ,那么 读 将阻塞到写入某些数据或者由打开管道进行写入的所有进程关闭管道为止。
- 如果设置了 O_NDELAY ,那么 读 子例程将返回值 0。
- 如果设置了 O_NONBLOCK ,那么 read 子例程将返回值 -1 并将全局变量 errno 设置为 EAGAIN。
当系统尝试从支持非分块读取的字符特殊文件 (例如,终端) 中进行读取,并且没有可用的数据时:
- 如果 O_NDELAY 和 O_NONBLOCK 已清除 (缺省值) ,那么 读 子例程会阻塞到数据变为可用为止。
- 如果设置了 O_NDELAY ,那么 读 子例程 0 返回 0。
- 如果设置了 O_NONBLOCK ,那么 read 子例程将返回 -1 ,并在没有可用数据的情况下将 errno 全局变量设置为 EAGAIN 。
当系统尝试读取支持实施方式记录锁定的常规文件,并且要读取的区域的全部或部分被另一个进程锁定时:
- 如果取消选中 O_NDELAY 和 O_NONBLOCK ,那么 读 会阻止调用过程,直到释放锁定为止。
- 如果设置了 O_NDELAY 或 O_NONBLOCK ,那么 读 将返回 -1 并将全局变量 埃尔诺 设置为再次。
中断的 读 子例程的行为取决于安装到达信号的处理程序的方式。
如果安装了处理程序,并且指示不得重新启动子例程,那么 read 子例程将返回值 -1 ,并且全局变量 errno 设置为 EINTR (即使已除去某些数据)。
如果已安装此处理程序,并指示必须重新启动子例程:
- 如果处理中断时未读取任何数据,那么此 读 不会返回任何值 (它将重新启动)。
- 如果在处理中断时读取了数据,那么此 读 子例程将返回除去的数据量。
read64x 子例程与 读 子例程相同,其中 扩展 参数是一个指向 j2_ext 结构的指针 (请参阅 j2/j2_cntl.h 文件)。 read64x 子例程用于以原始方式读取加密文件 (请参阅 fcntl.h 文件中的 O_RAW)。 在加密文件上使用 O_RAW 标志具有与在常规文件上使用 O_DIRECT 相同的限制。
从流中读取并检索消息的 埃雷阿德 和 埃雷亚德夫 子例程。 eread 子例程将数据的字节数从缓冲区复制到与 FileDescriptor 参数相关联的流。 Nbyte 参数可指定字节数。 缓冲区 参数指向此缓冲区。 在 标签 参数所指向的结构中,将返回安全性信息。
传播 函数执行与 读相同的操作,但它从文件中的给定位置进行读取,而不更改文件指针。 传播 的前三个自变量与 读 相同,但添加了第四个自变量,该自变量对于文件中的所需位置而言是偏移的。 尝试对无法查找结果的文件执行 传播 会导致错误。
ssize_t pread64(int fildes , void *buf , size_t nbytes , off64_t offset) pread64 子例程执行与 传播 相同的操作,但如果与文件描述符相关联的文件是块特殊文件或字符特殊文件,那么对与文件描述符和 DEV_OFF_MAX 相关联的文件的最大文件大小的偏移量限制。 如果 菲尔德斯 引用套接字,那么 读 等同于不设置任何标志的 接收 子例程。
将 读 或 传播 子例程与从对 Shm_open 子例程的调用中获取的文件描述符配合使用失败,并返回 ENXIO。
普雷亚德夫 子例程执行与 读 子例程相同的操作,但 普雷亚德夫 子例程在不更改文件指针的情况下从文件中的给定位置读取。 普雷亚德夫 子例程的前三个自变量与 读 子例程相同,并添加了 偏移 自变量,该自变量指向您希望在文件中的位置。 当 普雷亚德夫 子例程从其读取的文件无法查找时,发生错误。
参数
| 项 | 描述 |
|---|---|
| FileDescriptor | 这是一个文件描述符,用于标识要读取的对象。 |
| 扩展名 | 提供与需要更多信息或返回额外状态的字符设备驱动程序的通信。 每个驱动程序都以与设备相关的方式将 扩展 参数解释为值或指向通信区域的指针。 当 扩展 参数的值为 0 时,驱动程序必须应用合理的缺省值。 对于目录, 扩展 参数确定了必须返回目录条目的格式:
对于磁带设备, 扩展 参数确定当磁带机处于可变块方式且读请求小于磁带的块大小时, 读 子例程的响应。
|
| 伊奥夫 | 指向 伊奥韦茨 结构的数组,这些结构标识要将数据放置到其中的缓冲区。 iovec 结构在 sys/uio.h 文件中定义,并包含以下成员: |
| iovCount | 指定 伊奥夫 参数所指向的 伊奥韦茨 结构的数目。 |
| 缓冲区 | 指向该缓冲区。 |
| 字节数 | 指定从与文件描述符参数关联的文件中读取的字节数。 注: 读取磁带时, 读 子例程在每次调用子例程时都使用物理磁带块。 如果物理数据块大小大于 字节数 参数指定的大小,那么会返回一个错误,因为来自读取的所有数据都不适合读取操作指定的缓冲区。
要避免因磁带上未知块大小而导致的读错误,请将 字节数 参数设置为较大的值 (例如 32K 字节)。 |
| 偏移量 | 文件中的位置,从该位置开始读取。 |
| 标签 | 指向扩展的安全性属性结构。 |
返回值
成功完成后, 读, 读, read64x, 读, Readvx, 传播和 普雷亚德夫 子例程将返回已读取的字节数并放入缓冲区。 如果描述符引用在到达文件结束之前剩余的相同字节数的正常文件,那么系统保证读取所请求的字节数,但在任何其他情况下都是如此。
当到达文件的结尾时,返回值 0。 (有关通信文件的信息,请参阅 ioctl 和 泰尔米奥 文件。)
否则,返回值 -1 ,设置全局变量 errno 以标识错误,并且 Buffer 或 iov 参数指向的缓冲区内容不确定。
在成功完成后, 埃雷阿德 和 埃雷亚德夫 子例程将返回值 0。 否则,会将全局变量 错误号 设置为标识错误。
错误代码
如果下列其中一个或多个子例程为 true ,那么 读, 读, read64x, 读, Readvx, 传播, 埃雷阿德, 埃雷亚德夫和 普雷亚德夫 子例程不成功:
| 项 | 描述 |
|---|---|
| EBADMSG | 该文件是设置为 control-normal 方式的 STREAM 文件,并且等待读取的消息包含控制部分。 |
| EBADF | FileDescriptor 参数不是打开用于读取的有效文件描述符。 |
| EINVAL | 与 FileDescriptor 参数关联的文件位置指针为负数。 |
| EINVAL | 伊奥夫 数组中 iov_len 个值的总和为负数或溢出了 32 位整数。 |
| EINVAL | iovCount 参数的值不是 1-16 (含)。 |
| EINVAL | 在 32 位内核上请求了大于 OFF_MAX 的 字节数 参数的值。 此问题是从在 32 位内核上运行的 64 位应用程序请求系统调用时发生的情况。 |
| 项 | 描述 |
|---|---|
| EINVAL | FileDescriptor 所引用的 STREAM 或多路复用器是在多路复用器下游 (直接或间接) 链接的。 |
| EAGAIN | 该文件已标记为进行非阻塞 I/O ,并且未准备好读取任何数据。 |
| EFAULT | 缓冲区 或 伊奥夫 的部分指向进程的已分配地址空间之外的位置。 |
| EFAULT | 用户不具备访问 缓冲区的权限。 |
| EDEADLK | 如果调用进程进入休眠状态,直到要读取的区域解锁为止,那么将发生死锁。 |
| EINTR | 在任何数据到达之前, 读 被信号中断,并且安装了信号处理程序并指示不重新启动子例程。 |
| EIO | 从文件系统中读取时发生 I/O 错误。 |
| EIO | 该进程是正在尝试从其控制终端进行读取的后台进程的成员,并且该进程正在忽略或阻止 SIGTTIN 信号,或者该进程组没有父进程。 |
| EFBIG | 在 32 位内核上请求了大于 MAX_FILESIZE 的偏移量。 |
| ENXIO | 读 或 传播 子例程与从对 Shm_open 子例程的调用中获取的文件描述符一起使用。 |
| 项 | 描述 |
|---|---|
| Eoverflow | 尝试从 NBytes 大于零且起始偏移量在文件结束之前且大于或等于与 FileDescriptor相关联的打开文件描述中确定的最大偏移量的常规文件中读取。 |
如果以下情况成立,那么 读, 读, 读, Readvx, 传播和 普雷亚德夫 子例程可能不成功:
| 项 | 描述 |
|---|---|
| ENXIO | 对不存在的设备发出了请求,或者该请求超出了该设备的能力范围。 |
| EsPIPE | 菲尔德斯 与一个管道或 FIFO 关联。 |
如果系统上安装了网络文件系统 (NFS) ,那么如果满足以下条件,那么 read 系统调用也可能失败:
| 项 | 描述 |
|---|---|
| ETIMEDOUT | 这是已超时的连接。 |
| 项 | 描述 |
|---|---|
| EINVAL | 未正确初始化结构 j2_ext 。 例如,版本不正确,或者文件未加密。 |
| EINVAL | 对于未以原始方式打开的文件,传递了 j2_ext 结构,以发出 J2EXTCMD_RDRAW 命令。 |
| 项 | 描述 |
|---|---|
| ENOMEM | 内存或空间过少。 |
| EACCES | 许可权被拒绝。 用户没有足够的特权来读取数据。 |
| 开始 | ERESTART 用于确定系统调用是否是可重新启动的。 |
| 项 | 描述 |
|---|---|
| EINVAL | iovCount 参数的值大于 15。 |