名称:

pread,read-从文件读

语法:

#include <unistd.h>

ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
ssize_t read(int fildes, void *buf, size_t nbyte);

描述:

read()函数会尝试从fildes指定的文件描述符对应的文件中读取nbyte个字节,然后存放到buf中。同时对相同的管道、命名管道或终端设备的多个读取操作是未指定的

在下面描述的操作被执行之前,如果nbyte为0,read()函数会按照下面描述的方式检查并返回错误。如果没有错误,或者错误检测没有执行,read()会返回0没有进一步的结果

对于支持seek的文件(比如一个正常的文件),read()会从fildes中指定的偏移位置开始读取。偏移量会随着读取的字节数增长

对于不支持seek的文件(比如终端),始终从当前位置开始读。此种类型文件的偏移位置是未定义的

在当前文件结束位置之后不会进行任何数据的传输。如果起始位置在EOF及其之后都会导致read()函数返回0。如果文件是特殊设备文件,read()请求的结果是根据具体实现定义的

如果nbyte的值大于SSIZE_MAX,结果是根据定义实现的

当尝试从空管道或者空FIFO读取时:

  • 如果没有进程持有管道的写端,read()将返回0来指示EOF
  • 如果有进程持有写端,且O_NONBLOCK被置位,read()会返回-1并将errno设置为EAGAIN
  • 如果有进程持有写端,且O_NONBLOCK未被置位,read()会阻塞调用线程直到有数据被写入管道或者所有持有写端的进程被关闭

当尝试从一个支持非阻塞读的文件(非管道/匿名管道)读取,且当前没有数据可用时:

  • 如果O_NONBLOCK被置位,read()函数会返回-1并将errno设置为EAGAIN
  • 如果O_NONBLOCK没有置位,read()会阻塞调用线程直到有数据可用
  • O_NONBLOCK标志位的使用不会在有数据可用的时候产生影响

read()函数会从文件中读取之前写过的数据。如果文件EOF之前的数据还没有被写入,read()仍会返回数据但内容为0。例如,lseek()函数允许将偏移设置在当前已有数据之后的位置,随后就可以在这里写数据,在这两片数据之间的read()操作就会返回内容为0的数据

在函数成功执行之后,此时nbyte>0,read()会更新相关文件的最后数据获取时间戳,然后返回成功读取的字节数。返回的数字不会大于nbyte。返回值会在文件中剩余的字节少于nbyte个时小于nbyte,这种情况可能发生于read()请求被信号量打断、文件是管道/命名管道或者其他特殊文件在读取的时候立即可用的数据少于nbyte。比如,从和终端相关联的文件读取的数据可能就是一行字符

如果read()函数在读取任何数据之前被信号量打断,会返回-1并将errno设置为EINTR

如果read()函数在读取了一些数据之后被信号量打断,会返回成功读取的字节数

对于通常的文件,超过fildes指向的文件描述指定的最大偏移值的数据不会进行传输

如果fildes引用了socket,read()函数和没有设置flag的recv()相同

如果O_DSYNC和O_RSYNC被置位,在文件描述符上的读I/O操作将会按照同步I/O数据完整性的定义来完成;如果O_SYNC和O_RSYNC被置位,在文件描述符上的读I/O操作将会按照同步I/O文件完整性的定义来完成

如果fildes指向的是一个共享内存对象,读操作的结果将是未定义的

如果fildes指向的是一个类型内存对象,读操作的结果将是未定义的

从流文件读取的read()函数可以以三种模式读取数据:比特流模式、消息不保留模式、消息舍弃模式。默认是比特流模式。模式可以使用I_SRDOPT ioctl()请求修改,可以用I_GRDOPT ioctl()请求检测。比特流模式下,read()会尽可能多的从流中读取数据直到满足请求的数量或者流中没有数据,而忽视消息边界

在消息保留模式下,read()会尽可能多的读取数据直到满足请求或者达到消息边界。如果read()没有读取消息中所有的数据,剩下的数据仍会留在流中等待下一次读取。相反的,消息舍弃模式下,read()读取后消息中剩下的数据会被舍弃,后续如果有read()、getmsg()、getpmsg()也将无法读取到

read()处理0字节流的方式取决于当前的读取模式。字节流模式下,read()会持续读取数据直到满足nbyte个或者没有更多的数据或者遇到0字节消息阻塞。read()函数之后返回成功读取的字节数,并将0字节消息放回流中以待下一个read()、getmsg()、getpmsg()读取。在消息保留或消息舍弃模式下,遇到0字节消息之后将会返回0并将其从流中移除。如果0字节消息是流中读取的第一个消息,无论处于何种模式这个消息都会被舍弃并返回0

read()从流中读取数据的时候会返回流的头读取队列的最前面的消息,无论消息的优先级是什么

默认情况下,流是控制正常模式,在这种模式下read()只能从生成的消息中只包含数据而不包含控制部分的流文件。如果消息中包含了控制部分,read()就会失败。可以通过I_SRDOPT ioctl()命令改变默认的流模式为控制数据模式或者控制舍弃模式。在控制数据模式下,read()会将所有的控制部分转化为数据并在发送任何原生的数据部分之前将其发送。在控制舍弃模式下,read()会舍弃所有的控制部分

此外,如果在read()调用之前流的头就已经处理过一个异步错误,read()会失败。在这种情况下errno将不会反应read()的结果,而是反应之前的错误。如果read()读取的流出现了暂停,read()仍会继续执行直到流的头读取队列为空,然后返回0

pread()函数和read()函数基本一致,除了pread()会从给定的偏移位置读取而且不会改变偏移位置。pread()的第四个参数指定了偏移。如果指定了无法seek到的位置,蒋会导致错误

返回值:

在成功执行的情况下,这些函数会返回一个非负整数指明成功读取的字节数。否则函数会返回-1并设置errno指明错误

错误:

在下列情况下函数执行会失败:

EAGAIN:文件不是管道、命名管道、socket,文件描述符的O_NONBLOCK标志位被置位,读操作将会阻塞进程。

EBADF:fildes不是一个可用于打开并读取的文件描述符

EBADMSG:文件是流文件,而且待读取的消息中包含控制部分

EINTR:读操作被信号量中断,而且没有数据被传输

EINVAL:fildes指定的文件过着多路选择器是另一个多路选择器的下游

EIO:后台进程组的一个进程成员尝试从它的控制终端读取数据,而且调用线程关闭了SIGTTIN或者进程忽视了SIGTTIN或者进程所属的进程组是孤儿进程组。这个错误也可能因为具体实现定义的原因出现

EISDIR:fildes指向了一个目录,但是具体实现不允许read()或pread()读取目录。应该使用readdir()函数

EOVERFLOW:文件是正常文件,nbyte大于0,起始位置在EOF之前,但是起始位置大于或等于fildes指向的文件描述中指定的最大偏移值

pread()函数在下列情况下会失败:

EINVAL:指定的偏移量是负数,文件的偏移量将维持不变

ESPIPE:文件不支持seek

read()函数在下列情况下会失败:

EAGAIN:文件是管道或者命名管道,O_NONBLOCK标志位被置位,但是线程会被读操作阻塞

EAGAIN或EWOULDBLOCK:文件时socket,O_NONBLOCK被置位,但是线程会被读操作阻塞

ECONNRESET:尝试从一个被其上级强制关闭的socket读

ETIMEDOUT:尝试从socket中读的时候出现了超时

函数可能会在下列情况下失败:

EIO:物理I/O错误

ENOBUFS:系统资源不足以执行操作

ENOMEM:内存不足以支持操作

ENXIO:请求中含有不存在的设备,或者请求超出了设备的能力

C语言手册-read的更多相关文章

  1. 转:Egret社区翻译的《TypeScript语言手册》

      <TyptScript语言手册>第1章-介绍<TypeScript语言手册>第2章-基本概念<TypeScript语言手册>第3章-类型<TypeScri ...

  2. Linux-查看C语言手册及man的特殊用法

    man命令可以查看c语言库函数的函数原型, 比如 $ man malloc 如果显示 "No manual entry for malloc", 则需要安装 "man-p ...

  3. R语言手册

    在R的官方教程里是这么给R下注解的:一个数据分析和图形显示的程序设计环境(A system for data analysis and visualization which is built bas ...

  4. 一张方便的graphql schema 语言手册

    参考资料 https://github.com/sogko/graphql-schema-language-cheat-sheet        

  5. C语言分割字符串

    最近在做一道C语言题目的时候需要用到分割字符串,本来想自己手写的,也不会很麻烦,但想到其他语言都有分割字符串的库函数,C语言怎么会没有呢?所以,在网上搜了一搜,果然有这样的函数,还是很好用的,在此总结 ...

  6. 一周学会go语言并应用 by王奇疏

    <一周学会go语言并应用> by王奇疏 ( 欢迎加入go语言群: 218160862 , 群内有实践) 点击加入 零.安装go语言,配置环境及IDE 这部分内容不多,请参考我的这篇安装环境 ...

  7. ARM GCC 内嵌(inline)汇编手册

    转自:http://blogold.chinaunix.net/u2/69404/showart_1922655.html ARM GCC 内嵌(inline)汇编手册 百度云:http://pan. ...

  8. ARM GCC 内嵌汇编手册

    转自:http://blogold.chinaunix.net/u2/69404/showart_1922655.html ARM GCC 内嵌(inline)汇编手册 关于这篇文档这篇文章是本人为方 ...

  9. DOS程序员手册(三)

    56页     第4章DOS和BIOS接口     本章介绍了用户程序访问DOS内核和BIOS所提供的各种服务的方法.为了访问这 些服务,我们可以从任何编程语言中调用各个软件中断,这些中断便是我们在本 ...

随机推荐

  1. Debian下的内核编译

    如果你装了一台linux的机器,自己没有重新编译内核,那这台机器的效率就大打折扣了,因为默认安装的机器会生成许多不需要的东西,在启动的时候也会比较慢,而你要用的有些东西可能不能工作,比如,现在都把IP ...

  2. Java之秒杀活动解决方案

    0 引言 本文主要描述,服务端做相关秒杀活动的时候,对应的解决方案,即高并发下的数据安全. 1 优化方案 1.1 乐观锁思路 Redis中的watch,请求时,通过Redis查询当前抢购数据,如果当前 ...

  3. 趣学算法 PDF pdf 下载 陈小玉版

    趣学算法pdf高清无水印版下载 最近在网上找趣学算法pdf,最后还是买了完整版,今天将本书分享出来,分享给那些和我一样在网上苦苦寻找的小可爱们,有条件的话请支持正版! 链接:https://pan.b ...

  4. [CodeForces]529B Group Photo 2

    AK爷GhostCai的电脑又蓝屏了Orz 贪心题,确定一个maxh,限定h不大于一个值.枚举maxh. check的时候的细节很多: 1.h>maxh但w<maxh交换的时候需要占用交换 ...

  5. axios统一拦截配置

    在vue项目中,和后台进行数据交互使用axios.要想统一处理所有的http请求和响应,就需要使用axios的拦截器.通过配置http response inteceptor 统一拦截后台的接口数据, ...

  6. Python-基础-day5

    1.内置函数 2.文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 文件句柄 = file('文件路径', '模式') 注:python中打开文件有两种方式,即:open ...

  7. java--web学习总结<转>

    http://www.cnblogs.com/xdp-gacl/p/3729033.html

  8. Java分布式爬虫Nutch教程——导入Nutch工程,执行完整爬取

    Java分布式爬虫Nutch教程--导入Nutch工程,执行完整爬取 by briefcopy · Published 2016年4月25日 · Updated 2016年12月11日 在使用本教程之 ...

  9. 20个C#热点问题

  10. 字符串的HashCode可能相同

    字符串的HashCode可能相同 学习了:http://blog.csdn.net/hl_java/article/details/71511815