名称:

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. ABBYY迎国庆·庆中秋限时折扣狂潮,再来一波

    继ABBYY 早秋限时活动之后,ABBYY官方为迎国庆,庆中秋,折扣狂潮,又来一波.上次活动由于时间短,任务急,数量少,使得不少小伙伴抱憾而止,选择默默等待良机.现在,良机来了,即便没有上次的打折力度 ...

  2. ZBrush与同类数字雕刻软件的比较

    随着数字雕刻软件的迅猛发展,不但在软件的数量和功能上有突飞猛进的提高,行业应用上也有很大的拓展.那么,与同类数字雕刻软件比较下,用户应该如何选择呢?下面我们来对这些软件做一个简单的罗列分析. 目前数字 ...

  3. uva 11300 Spreading the Wealth_数学推倒 + 思维

    这道题和负载平衡问题是同一道题, 如果 n<=100n <= 100n<=100 的话是可以用最小费用流来求解的. 但是题中 nnn 最大可达到 10610^6106, 这就需要我们 ...

  4. 扩展Jmeter--BeanShell进行java扩展

    1.在eclipse中写第一个java 程序,导出成jar文件,在Jmeter安装文件下新建一个dependences文件夹,将导出的.jar包文件放在文件夹下. 2.修改Jmter安装文件bin目录 ...

  5. 启用Maven的代理访问

    1. Maven配置文件 找到文件 {M2_HOME}/conf/settings.xml, 并把你的代理服务器信息配置写入.注:{M2_HOME} => D:\software\yiibai. ...

  6. 题解 P1774 【最接近神的人_NOI导刊2010提高(02)】

    这道题很明显是求逆序对. 所谓逆序对,就是逆序的数对. 譬如在下面这个数列中: 1 2 3 4 6 5 6 5就是一个逆序对. 求逆序对的方法比较多,常见的有归并排序和树状数组(线段树当然也行). 本 ...

  7. C#-委托 lambda 匿名方法 匿名类型

    1.lambda 匿名方法 匿名类型 delegate void d1(); d1 d = delegate(){Console.WriteLine("this is a test" ...

  8. U盘无法格式化的恢复

    昨天装Ubuntu的系统可能把U盘搞崩溃了.然后今早起来U盘无法识别,格式化也不行,用Windows的磁盘管理工具格式化说是:Windows无法格式化U盘. 曾经没遇到这样的情况,所以百度了一下,试了 ...

  9. 电脑显示U盘,可是读取不了

    问题: 我的一个内存卡没用,放到了读卡器上.刚開始能用,可是到了后来,突然之间发现: 插入读卡器之后,仅仅是在U下角显示有有U盘提示,提示"打开设备和打印"或者"安全删除 ...

  10. 调用支付宝SDK问题

    近期做了一个项目里面要有支付.银联.支付宝,微信支付 我先一个一个写吧 先说支付宝SDK 支付宝SDK放进project里面之后肯定会报错.这时候你就要一个一个改掉 1. 2. 3. 哎 我懒得写了. ...