名称:

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. Django中ORM之创建模型

    ORM 数据库与ORM映射关系 表名 --- 类名 字段 --- 属性 表记录 --- 类示例对象 创建表(建立模型) 模型建立如下 class Book(models.Model): title = ...

  2. jupyter的安装

    3.6:\Lib\site-packages\pip\models\index.py # PyPI = Index('https://pypi.python.org/') # 替换成 PyPI = I ...

  3. Python 九九乘法表打印

    Python 九九乘法表打印 小练习 for i in range(1,10,1): for j in range(1,i+1): print("%s*%s=%s" %(j,i,i ...

  4. 算法27-----第N个数字

    1.题目: 在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...中找到第 n 个数字. 注意: n 是正数且在32为整形范围内 ( n < 231). ...

  5. 模板 NTT 快速数论变换

    NTT裸模板,没什么好解释的 这种高深算法其实也没那么必要知道原理 #include <cstdio> #include <cstring> #include <algo ...

  6. Python 绘图与可视化 matplotlib(下)

    详细的参考链接:更详细的:https://www.cnblogs.com/zhizhan/p/5615947.html 图像.子图.坐标轴以及记号 Matplotlib中图像的意思是打开的整个画图窗口 ...

  7. Docker决战到底(三) Rancher2.x的安装与使用 - 简书

    原文:Docker决战到底(三) Rancher2.x的安装与使用 - 简书   image.png 当越来越多的容器化应用被部署,一个可以管理编排这些容器的工具此时就显得尤为重要了.目前容器编排领域 ...

  8. 阿里云Linux系统Nginx配置多个域名的方法

    Nginx绑定多个域名,可通过把多个域名规则写一个配置文件里实现,也可通过分别建立多个域名配置文件实现,为了管理方便,建议每个域名建一个文件,有些同类域名则可写在一个总的配置文件里. 1. 比如我想建 ...

  9. Shiro:授权的相关实现

    Shiro:授权的相关实现 一.使用Shiro过滤器实现授权 设置好授权拦截跳转的请求地址 /** * 创建ShiroFilterFactoryBean */ @Bean public ShiroFi ...

  10. 【codeforces 738E】Subordinates

    [题目链接]:http://codeforces.com/problemset/problem/738/E [题意] 给你一个类似树形的关系; 然后告诉你某个人头顶上有多少个上司numi; 只有fat ...