• RIO包 健壮的I/O函数代码


    下面是关于
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    
    #define MAXLINE 1024
    
    /*unbuffer input/output function*/
    
    ssize_t rio_readn(int fd,void *usrbuf,size_t n)
    {
        size_t nleft = n;
        ssize_t nread;
        char *bufp = usrbuf;
    
        while(nleft > 0){
            if((nread = read(fd,bufp,nleft)) < 0){
                if(errno == EINTR){/*interrupted by sig handler return*/
                    nread = 0;
                }else{
                    return -1;/*error*/
                }
            }else if(nread == 0){
                break;  /*EOF*/
            }else{/*read content*/
                nleft -= nread;
                bufp += nread;
            }
        }
        return (n - nleft);
    }
    
    ssize_t rio_writen(int fd,void *usrbuf,size_t n)
    {
        size_t nleft = n;
        ssize_t nwritten;
        char *bufp = usrbuf;
    
        while(nwritten = write(fd,bufp,nleft) <= 0){
            if(errno == EINTR){
                nwritten = 0;
            }else{
                return -1;
            }
            nleft -= nwritten;
            bufp += nwritten;
        }
        return n;
    }
    /******************************************************************************/
    #define RIO_BUFSIZE 8192
    typedef struct{
        int rio_fd; /*To operate the file descriptor*/
        int rio_cnt;/*unread bytes in internal buf*/
        char *rio_bufptr;/*next unread byte int internal buf*/
        char rio_buf[RIO_BUFSIZE];/*internal buf*/
    }rio_t;
    void rio_readinitb(rio_t *rp,int fd)
    {
        rp->rio_fd = fd;
        rp->rio_cnt = 0;
        rp->rio_bufptr = rp->rio_buf;
    }
    static ssize_t rio_read(rio_t *rp,char *usrbuf,size_t n)
    {
        int cnt;
        while(rp->rio_cnt <= 0){/*Read the file content if buf is empty*/
            rp->rio_cnt = read(rp->rio_fd, rp->rio_buf,sizeof(rp->rio_buf));
            if(rp->rio_cnt < 0){
                if(errno != EINTR){
                    return -1;
                }
            }else if(rp->rio_cnt == 0){/*EOF*/
                return 0;
            }else {/*reset buf ptr*/
                rp->rio_bufptr = rp->rio_buf;
            }
        }
        /*when n < rp->rio_cnt, need copy some times */
        cnt = n;
        if(rp->rio_cnt < n){/*one time copy end*/
            cnt = rp->rio_cnt;
        }
        memcpy(usrbuf,rp->rio_bufptr,cnt);
        rp->rio_bufptr += cnt;
        rp->rio_cnt -= cnt;
        return cnt;
    }
    ssize_t rio_readlineb(rio_t *rp, void *usrbuf,size_t maxlen)
    {
        int n,rc;
        char c,*bufp = usrbuf;
        for(n = 1; n < maxlen; n++){
            if (( rc = rio_read(rp,&c,1)) == 1){
                *bufp++ = c;
                if(c == '
    '){
                    break;
                }
            }else if (rc == 0){
                if(n == 1){/*EOF no data read*/
                    return 0;
                }else{/*EOF some data read*/
                    break;
                }
            }else{/*ERROR*/
                return -1;
            }
        }
        *bufp = 0;/*string end sign :''*/
        return n;
    }
    
    ssize_t rio_readnb(rio_t *rp,void *usrbuf,size_t n)
    {
        size_t nleft = n;
        ssize_t nread;
        char *bufp = usrbuf;
    
        while(nleft > 0){
            if((nread = rio_read(rp,bufp, nleft)) < 0){
                if(errno == EINTR){/*interrupted by sig handler return*/
                    nread =0;
                }else{/*errno set by read() */
                    return -1;
                }
            }else if(nread == 0){/*EOF*/
                break;
            }
            nleft -= nread;
            bufp += nread;
        }
        return (n-nleft);/*return >=0*/
    }
    
    int main()
    {
        int n;
        rio_t rio;
        char buf[MAXLINE];
    
        int fd = open("1.txt",O_RDONLY,755);
        if(fd <=0){
            printf("error
    ");
        }
        rio_readinitb(&rio,fd);
        while ((n = rio_readlineb(&rio,buf,MAXLINE)) != 0){
               rio_writen(1,buf,n);
        }
        close(fd);
        return 0;
    }


    上面的函数式RIO包提供的两类不同的函数:

    1、不带缓冲的输入输出函数

    2、带缓冲的输入函数

    这里主要针对文件Io,因为标准Io本身就是带缓冲的,我们在对文件进行读写操作时,一般会优先使用标准的Io函数,但是在网络编程中,只能使用文件Io的函数,这里可能就用到我们上面的函数编写,有兴趣的可以多了解下上面的机制。在网络通信中,这种机制方法运用还是比较多的!

  • 相关阅读:
    bzoj3028食物 关于(1+x+x^2+x^3+x^4+...)^k的第i项系数就是c(i+k−1,k−1)的证明
    一个好玩的题--倒水
    HDU4372(第一类斯特林数)
    MySQL常用基本语句
    腾讯windows客户端一面
    腾讯PC客户端开发方向一面
    LeetCode数据库175
    Intern Day47
    Intern Day46
    Intern Day46
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3151171.html
Copyright © 2020-2023  润新知