高级I/O之readn和writen函数
管道、FIFO以及某些设备,特别是终端、网络和STREAMS设备有下列两种性质:
(1)一次read操作所返回的数据可能少于所要求的数据,即使还没有达到文件尾端也可能是这样。这不是一个错误,应当继续读该设备。
(2)一次write操作的返回值也可能少于指定输出的字节数。这可能是由若干因素造成的,例如,下游模块的流量控制限制。这也不是错误,应当继续写余下的数据至该设备。(通常,只有对非阻塞描述符,或捕捉到一个信号时,才发生这种write的中途返回。)
在读、写磁盘文件时从未见到过这种情况,除非文件系统用完了空间,或者我们接近了配额限制,而不能将要求写的数据全部写出。
通常当读、写一个管道、网络设备或终端时,我们需要考虑这些特性。下面两个函数readn和writen的功能是读、写指定的N字节数据,并处理返回值小于要求值的情况。这两个函数只是按需多次调用read和write直至读、写了N字节数据。
#include "apue.h"
ssize_t readn(int filedes, void *buf, size_t nbytes);
ssize_t writen(int filedes, void *buf, size_t nbytes);
两个函数返回值:已读、写字节数,若出错则返回-1
注:readn和writen这两个函数是我们自己定义的,只是为了以后方便使用。它们并非任何标准的组成部分。
在要将数据写到上面提到的文件类型上时,就可调用writen,但是只有当事先就知道要接收数据的数量时,才调用readn(通常只调用read接收来自这些设备的数据)。
程序清单14-11包含了writen和readn的一种实现。
程序清单14-11 readn和writen函数
#include "apue.h" size_t /* Read "n" bytes from a descriptor */
readn(int fd, void *ptr, size_t n)
{
size_t nleft;
ssize_t nread; nleft = n;
while (nleft > 0)
{
if ((nread = read(fd, ptr, nleft)) < 0)
{
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount read so far */
}
else if (nread == 0)
{
break; /* EOF */
}
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
} ssize_t /* Write "n" bytes to a descriptor */
writen(int fd, const void *ptr, size_t n)
{
size_t nleft;
ssize_t nwritten; nleft = n;
while (nleft > 0)
{
if ((nwritten = write(fd, ptr, nleft)) < 0)
{
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount written so far */
}
else if (nwritten == 0)
{
break;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n - nleft); /* return >= 0 */
}
注意,若在已经读、写了一些数据后出错,则这两个函数返回已经传输的数据量,而非出错返回。与此类似,在读时如达到文件尾,而且在此之前已经成功地读了一些数据,但尚未满足所要求的量,则readn返回已复制到调用者缓冲区中的字节数。
本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。
高级I/O之readn和writen函数的更多相关文章
- Linux网络编程-readn函数、writen函数、readline函数实现
readn函数功能:在网络编程的读取数据中,通常会需要用到一个读指定字节才返回的函数,linux系统调用中没有给出,需要自己封装. readn实现代码: int readn(int fd, void ...
- 网络编程readn、writen和readline函数的编写
readn 在Linux中,read的声明为: ssize_t read(int fd, void *buf, size_t count); 它的返回值有以下情形: 1.大于0,代表成功读取的字节 ...
- 【读书笔记】读《JavaScript高级程序设计-第2版》 - 非函数部分
章节列表: 第08章:BOM 第09章:客户端检测 第10章:DOM 第11章:DOM2和DOM3 第12章:事件 第13章:表单脚本 第14章:错误处理与调试 第17章:Ajax和JSON第20章: ...
- 高级I/O之readv和writev函数
readv和writev函数用于在一次函数调用中读.写多个非连续缓冲区.有时也将这两个函数称为散布读(scatter read)和聚集写(gather write). #include <sys ...
- JavaScript高级程序设计(读书笔记)之函数表达式
定义函数的方式有两种:一种是函数声明,另一种就是函数表达式. 函数声明的一个重要特征就是函数声明提升(function declaration hoisting),意思是在执行代码前会先读取函数声明. ...
- 【Unix环境高级编程】编写变长参数函数
文件的格式输入输出函数都支持变长参数.定义时,变长参数列表通过省略号'...'表示, 因此函数定义格式为: type 函数名(parm1, parm2,parmN,...); Unix的变长参数通过v ...
- 《Javascript高级程序设计》读书笔记之bind函数详解
为什么需要bind var name = "The Window"; var object = { name: "My Object", getNameFunc ...
- Oracle 高级查询、事物、过程及函数
一.Sql函数 1.数值函数(输入参数和返回值都是数值型,多数函数精确到38位) --多少次方 ,) from dual; --开方 ) from dual; --绝对值 ) from dual; - ...
- UNIX环境高级编程——信号基本概述和signal函数
一.为了理解信号,先从我们最熟悉的场景说起:1. 用户输入命令,在Shell下启动一个前台进程.2. 用户按下Ctrl-C,这个键盘输入产生一个硬件中断.3. 如果CPU当前正在执行这个进程的代码,则 ...
随机推荐
- HDU-4035 Maze
http://acm.hdu.edu.cn/showproblem.php?pid=4035 树上的概率dp. Maze Time Limit: 2000/1000 MS (Java/Others ...
- 取requests返回字典值用json()
python模块requests返回值用json()["h"][key]可以取出下面的value
- Linux操作系统上用数据泵导库
1.在Linux上 创建物理目录dp_dir,存放数据库.dmp文件: 用root用户登录,切换到oracle用户,用oralce身份创建物理目录如下: [root@server36 oracle]# ...
- Fitnesse+RestFixture:Web服务回归测试利器
RestFixture是Fitness的一个测试REST服务的插件,用于调用标准的http GET/POST等请求方法,并可以用XPath语法和Javascript语法检验http响应.本文介绍安装运 ...
- 告别where 1=1 最佳方案分享
已经有2年没有用过where 1=1了,没想到换了家公司后,又让我看到了它.在网络上面搜索了一下,发现没有人提供一个比较好的方案来解决这一问题.很多人说可以让数据库的优化机制去处理,但是,我想对于大部 ...
- 基于51,人体红外感应和RC522的门禁系统
总结一下最近学的东西,这两天学的东西,rfid门卡系统终于弄出来来了,这个程序算现在写过的比较满意的程序,大家可以参考参考 主函数: #include<reg52.h> #include& ...
- VB调用自持字体
VB调用自制字体我这里有一个C#的例子,请问如何在VB中实现啊. 我们写exe程序时,默认字体是宋体,比较难看,指定了其他字体,但是其他用户上没有你指定的这个字体的话,也会变成默认的宋体.解决的办法有 ...
- Hadoop port to Jxta P2P Framework
https://www.java.net/forum/topic/jxta/jxta-community-forum/hadoop-port-jxta-p2p-framework —————————— ...
- Codeforces 602B Approximating a Constant Range(想法题)
B. Approximating a Constant Range When Xellos was doing a practice course in university, he once had ...
- java线程中的wait和notify以及notifyall
一.区别与联系 1.1.wait(),notify()和notifyAll()都是java.lang.Object的方法,而确实sleep方法是Thread类中的方法,这是为什么呢? 因为wait和 ...