高级I/O之readn和writen函数

转载 2016年08月30日 22:21:31

管道、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的一种实现。

ssize_t /* Read "n" bytes from a descriptor. */
readn(int fd, void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nread;
    char *ptr;
    ptr = vptr;
    nleft = n;
    while(nleft > 0)
    {
        if(nread = read(fd, ptr, nleft)) < 0)
        {
            if(errno == EINTR)
                nread = 0; /* and call read() again */
            else
                return (-1);
        }
        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 *vptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;
    ptr = vptr;
    nleft = n;
    while(nleft > 0)
    {
        if((nwritten = write(fd, ptr, nleft) <= 0)
        {
            if(nwritten <0 && errno == EINTR)
                nwritten = 0; /* and call write() again */
            else
                return (-1); /* error */
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return n;
}

http://www.cnblogs.com/nufangrensheng/archive/2014/02/21/3559381.html

相关文章推荐

UNIX安全读写函数——readn和writen

UNIX安全读写函数——readn和writen前言:字节流套接字(TCP套接字)上的read和write函数所表现的行为不同于通常的文件I/O。字节流套接字调用read或write输入或输出的字节数...

readn和writen函数实现通信

readn()和writen()并非任何标准的组成部分,这两个函数是我们自己定义的,只是为了使用方便。以下是笔者自己实现的readn和writen函数,可用于客户端和服务器端进行通信,测试时先将服务器...

readn,writen,readline函数

字节流套接字上的read和write函数所表现的行为不同于通常的文件I/O。字节流套接字上调用的read和write输入或输出的字节数可能比请求的数量少,然而这不是出错的状态,这个现象的原因在于内核中...

关于 readn、writen 函数--read返回值分析

编辑时间: 2015.8.22.18.46 注意: 研究zebra 的 vtysh端的 阻塞与非阻塞 时,看到readn及writen, 所以 转载一些 感觉写的较好的,以防收藏被删。 一、z...

unix网络编程readn,writen,readline包裹函数

一、Readn包裹函数 /* include readn */ #include "unp.h" ssize_t /* Read "n" bytes from a descriptor. */ rea...

readn,writen和readline函数

readn函数:从一个描述符读n字节 #include "unp.h" ssize_t readn(int fd, void* vptr, size_t n) { size_t nleft; ssiz...

UNIX网络编程卷1:套接字联网-第3章:套接字编程-readn,writen函数

既然我们已经有了系统提供的接口read和write,为什么还需要readn writen 和readline呢?  因为字节流套接字上调用read或write输入和输出的字节数可能比请求的数量少,然...

readn和writen函数, socket编程常用函数

写函数write  #include ssize_t write(int fildes,const void *buf,size_t nbyte)  write函数将buf中的nbyte字...

高级I/O函数之socketpair

pipe函数可用于创建一个管道,以实现进程间的通信。但是单个管道只能单向通信,一端用于读,一端用于写。若要实现双向通信,必须创建一对管道。而socketpair函数能够创建双向管道。 int sock...

Linux 高级I/O函数

一、pipe()函数 1.1、pipe函数创建一个管道,以实现进程间通信。 1.2、int pipe(int fd[2]),pipe函数的参数是一个包含两个int型整数的数组指针。函数成功时返回0...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高级I/O之readn和writen函数
举报原因:
原因补充:

(最多只允许输入30个字)