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             else
14                 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  >= 0
22 }

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             else
14                 return -1;//error write
15         }
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 read
17             else
18                 break;//EOF, some data was read
19         }else
20             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             else
14                 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             else
18                 break;
19         }else
20             return -1;
21     }
22     *buf = ‘\0‘;
23     return n;
24 }

readn,writen,readline,布布扣,bubuko.com

时间: 2024-10-10 16:28:18

readn,writen,readline的相关文章

0723------Linux基础----------文件 IO 之 read 和 write (readn 、writen、readline)

1. readn 和 writen 1.1 基础巩固: read 和 write 函数的返回值 1.1.1 read 函数原型为:ssize_t  read(int fd, void* buf, size_t count); (这里的 void *在标准 C 中表示通用指针即任意类型的指针都可以对它赋值,ssize_t 是有符号整数)它的返回值如下: a)成功返回读取的字节数,这里可能等于 count 或者小于 count (当 count > 文件 size 的时候,返回实际读到的字节数):

网络编程readn、writen和readline函数的编写

readn   在Linux中,read的声明为: ssize_t read(int fd, void *buf, size_t count); 它的返回值有以下情形: 1.大于0,代表成功读取的字节数 2.等于0,代表读取到了EOF,一般是对方关闭了socket的写端或者直接close 3.小于0,出现错误. 我们编写一个readn函数,声明与read一致,但是,readn在未出错或者fd没有关闭的情况下,会读满count个字节. ssize_t readn(int fd, void *buf

JAVA之旅(二十五)——文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine

JAVA之旅(二十五)--文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine 我们继续IO上个篇幅讲 一.文本复制 读写都说了,我们来看下其他的操作,我们首先来看复制 复制原理:其实就是将C盘下的文件数据存储到D盘的一个文件中 实现的步骤: 1.在D盘创建一个文件,用于存储文件中的数据 2.定义读取流和文件关联 3.通过不断的读写完成数据的存储 关闭资源 package com.lgl.hel

几种并发服务器模型的实现:多线程,多进程,select,poll,epoll

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <arpa/inet.h> #include &q

0730------Linux网络编程----------服务器端模型(迭代,多进程,多线程,select,poll,epoll 等)

1.迭代服务器模型 1.1 迭代服务器是处理多个请求时一种最简单直接的思路,即使用while循环,它不具有并发能力,即必须一个一个的处理客户的请求. 1.2 程序示例. #include "def.h" int listenfd_init(); //返回一个处于监听状态的套接字描述符 void do_service(int peerfd); // 处理客户端的请求 int main(int argc, const char *argv[]) { if(signal(SIGPIPE, S

写一个方法求数组中的最大值,最小值,总和以及平均值。

class Program { /// <summary> /// 求数组中的最大值,最小值,总和以及平均值. /// </summary> /// <param name="nums">输入一个数组</param> /// <returns>返回一个新的数组(max,min,sum,avg)</returns> public static int[] GetMaxMinSumAvg(int[] nums) { i

Python3 文件读写r,w,a

1 # Author;Tsukasa 2 ''' 3 f = open('yesterday','w') #文件句柄...注意open分为'r'读模式,'w'写模式(d会先创建文件或者覆盖文件),'a'为追加模式(添加), 4 #data = f.read()#读取文件read() 5 f.write('hello') #注意如果要写文件的话 上面open模式要改 6 7 8 f = open('yesterday','a') 9 print(f.tell())#打印当前光标位置 10 #pri

文成小盆友python-num3 集合,函数,-- 部分内置函数

本接主要内容: set -- 集合数据类型 函数 自定义函数 部分内置函数 一.set 集合数据类型 set集合,是一个无序且不重复的元素集合 集合基本特性 无序 不重复 创建集合 #!/bin/env python s1 = {"1","2","3","4"} ##或者 s2 = set() set 提供的功能 1 class set(object): 2 """ 3 set() -> n

穹举,迭代,while循环。

所有循环  必要条件 :   初始条件(注意初始条件的位置)   循环条件   循环体   状态改变: 1.穷举 将所有可能性全部全部走一遍,使用IF筛选出满足的情况 使用循环语句    for   或者  while 语句   do ...while   语句  中间嵌套  if 语句 举例 1, 穷举:将所有可能性全部走一遍,使用if筛选出满足的情况            单位给发了一张150元购物卡,            拿着到超市买三类洗化用品.            洗发水15元,香