首页 > 代码库 > readn,writen,readline
readn,writen,readline
unix的RIO提供的readn,writen,readline两类不同的函数:
1.无缓冲区的输入输出函数
rio_readn
1 ssize_t rio_readn(int fp, void *usrbuf, size_t n) 2 { 3 size_t nleft = n; 4 ssize_t nread; 5 char *bufp = usrbuf; 6 7 while(nleft > 0)//未读取一定数目的继续读,直到读取满足数目的字节 8 { 9 if((nread = read(fd, bufp, nleft)) < 0)10 {11 if(errno == EINTR)12 nread = 0;//继续重新读13 else14 return -1;/*error read*/15 }16 else if(nread == 0)17 break; /*EOF*/18 nleft -= nread;19 bufp += nread;20 }21 return (n - nleft);//return >= 022 }
rio_writen
1 ssize_t rio_writen(int fd, char *usrbuf, size_t n) 2 { 3 size_t nleft = n; 4 ssize_t nwritten; 5 char *bufp = usrbuf; 6 7 while(nleft > 0) 8 { 9 if((nwritten = write(fd, bufp, nleft)) <= 0)10 {11 if(errno == EINTR)12 nwritten = 0;13 else14 return -1;//error write15 }16 nleft -= nwritten;17 bufp += nwritten;18 }19 return n;20 }
rio_readline
1 ssize_t rio_readline(int fp, void *usrbuf, size_t maxlen) 2 { 3 char c, *buf = usrbuf; 4 int n, cnt; 5 6 for(n = 1; n < maxlen; n++) 7 {//每次读取一个字符并判断,最后加个‘\0‘,实现字符串的输出 8 if((cnt = read(rp, &c, 1)) == 1) 9 {10 *buf++ = c;11 if(c == ‘\n‘)//找到一行末尾,退出12 break;13 }else if(cnt == 0)14 {15 if(n == 1)16 return 0;//EOF, no data read17 else18 break;//EOF, some data was read19 }else20 return -1;21 }22 *buf = ‘\0‘;23 return n;24 }
2.带缓冲区的输入函数
核心:定义了一个含有字符数组的结构体
1 #define MAXLINE 1024 2 #define RIO_BUFFER 8192 3 typedef struct 4 { 5 int fd_; 6 int left_; 7 char *bufptr_; 8 char buff_[RIO_BUFFER]; 9 }rio_t;10 11 void rio_init(rio_t *rp, int fd)12 {13 rp->fd_ = fd;14 rp->left_ = 0;15 rp->bufptr_ = rp->buff_;16 }//初始化结构体
rio_read 函数功能:调用rio_read读n个字节时,读缓冲区内有rp->left_个字节,缓冲区为空,会通过read再填满缓冲区,缓冲区非空,rio_read从缓冲区拷贝n和
rp->left_ 中较小值个字节到用户缓冲区(usrbuf)中,并且返回拷贝的字节数
1 ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n) 2 { 3 ssize_t nread; 4 while(rp->left_ <= 0)//缓冲区中没有内容时从文件中读, 5 { 6 nread = read(rp->fd_, rp->bufptr_, sizeof(rp->buff_)); 7 if(nread == -1) 8 { 9 if(errno == EINTR)10 continue;11 return -1;12 }else if(nread == 0)13 return 0;14 rp->left_ = nread;15 rp->bufptr_ = rp->buff_;//重置指针16 }17 18 int cnt = n;19 if(rp->left_ < n)20 cnt = rp->left_;//取两者较小值21 memcpy(usrbuf, rp->bufptr_, cnt);//从缓冲区中读内容到传进来的字符指针中22 rp->left_ -= cnt;//剩余缓冲区大小和指针都要变化23 rp->bufptr_ += cnt;24 return cnt;25 }
rio_readnb 从结构体中读取n个字节,与无缓冲区的不同就是此时是从rio结构体的缓冲区中读取而不是直接从内核读取
1 ssize_t rio_readn(rio_t *rp, void *usrbuf, size_t n) 2 { 3 size_t nleft = n; 4 ssize_t nread; 5 char *bufp = usrbuf; 6 7 while(nleft > 0)//未读取一定数目的继续读,直到读取满足数目的字节 8 { 9 if((nread = rio_read(rp, bufp, nleft)) < 0)10 {11 if(errno == EINTR)12 nread = 0;//继续重新读13 else14 return -1;15 }16 else if(nread == 0)17 break;18 nleft -= nread;19 bufp += nread;20 }21 return (n - nleft);22 }
rio_readlineb
1 ssize_t rio_readline(rio_t *rp, void *usrbuf, size_t maxlen) 2 { 3 char c, *buf = usrbuf; 4 int n, cnt; 5 6 for(n = 1; n < maxlen; n++) 7 {//每次读取一个字符并判断,最后加个‘\0‘,实现字符串的输出 8 if((cnt = rio_read(rp, &c, 1)) == 1) 9 {10 *buf++ = c;11 if(c == ‘\n‘)//找到一行末尾,退出12 break;13 }else if(cnt == 0)14 {15 if(n == 1)16 return 0;17 else18 break;19 }else20 return -1;21 }22 *buf = ‘\0‘;23 return n;24 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。