首页 > 代码库 > 封装readn

封装readn

  1 #include <stdio.h>  2 #include <stdlib.h>  3 #include <string.h>  4 #include <unistd.h>  5 #include <sys/types.h>  6 #include <sys/stat.h>  7 #include <fcntl.h>  8 #include <sys/wait.h>  9 #include <errno.h> 10 #define ERR_EXIT(m)  11     do {  12         perror(m); 13         exit(EXIT_FAILURE); 14     }while(0) 15  16 #define BUFFERSIZE 65536  //缓冲区大小 17  18 typedef struct                  //缓冲区封装为一个结构体   19 { 20     int fd_; //fd 21     int cnt_; //缓冲区可用的字节数 22     char *ptr_; //指向缓冲区可用的第一个字节 23     char buffer_[BUFFERSIZE]; //缓冲区 24 } rio_t; 25  26 //初始化IO系统 27 void rio_init(rio_t *rp, int fd) 28 { 29     rp->fd_ = fd; 30     rp->cnt_ = 0; 31     rp->ptr_ = rp->buffer_; 32     memset(rp->buffer_, 0, BUFFERSIZE); 33 } 34  35 //用来替换read 36 ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n) 37 { 38  39     //缓冲区为空时,执行read操作 40     while(rp->cnt_ <= 0) 41     { 42         ssize_t nread = read(rp->fd_, rp->buffer_, BUFFERSIZE); 43         if(nread == -1) 44         { 45             if(errno == EINTR) 46                 continue; 47             return -1;  //ERROR 48         } 49         else if(nread == 0) 50             return 0; 51  52         //正常读取 53         rp->cnt_ = nread; 54         rp->ptr_ = rp->buffer_; //重置指针 55     } 56  57     //现有库存和用户要求的数量 取较小者 58     int cnt = (rp->cnt_ < n) ? rp->cnt_ : n; 59     memcpy(usrbuf, rp->ptr_, cnt); 60     rp->ptr_ += cnt; 61     rp->cnt_ -= cnt; 62  63     return cnt;  //成功读取的字节数 64 } 65  66  67 ssize_t rio_readn(rio_t *rp, void *buf, size_t count) 68 { 69     size_t nleft = count;  //剩余的字节数 70     ssize_t nread; //用作返回值 71     char *bufp = (char*)buf; //缓冲区的偏移量 72  73     while(nleft > 0) 74     { 75         //不再执行read系统调用 76         nread = rio_read(rp, bufp, nleft); 77         if(nread == -1) 78         { 79             if(errno == EINTR) 80                 continue; 81             return -1; // ERROR 82         } 83         else if(nread == 0) //EOF 84             break; 85  86         nleft -= nread; 87         bufp += nread; 88     } 89  90     return (count - nleft); 91 } 92  93 ssize_t rio_readline(rio_t *rp, char *usrbuf, size_t maxlen) 94 { 95     int i; //计数 96     int nread; 97  98     char *bufp = usrbuf; 99     char c; //暂存字符100 101     for(i = 0; i < maxlen - 1; ++i)102     {103         if((nread = rio_read(rp, &c, 1)) == -1)104             return -1;105         else if(nread == 0) //EOF106         {107             if(i == 0)108                 return 0;109             break;110         }111 112         *bufp++ = c; //放入usrbuf113         if(c == \n) //碰到换行符直接退出循环114             break; 115     }116     *bufp = \0;117     return i; //返回读取的字节数 118 }119 120 121 ssize_t rio_writen(int fd, const void *buf, size_t count)122 {123     size_t nleft = count;124     ssize_t nwrite;125     const char *bufp = (const char*)buf;126     127     while(nleft > 0)128     {129         nwrite = write(fd, bufp, nleft);130         if(nwrite <= 0) // ERROR131         {132             if(nwrite == -1 && errno == EINTR)133                 continue;134             return -1;135         }136 137         nleft -= nwrite;138         bufp += nwrite;139     }140     141     return count;142 }143 144 145 int main(int argc, const char *argv[])146 {147     int fd = open("test.txt", O_RDONLY);148     if(fd == -1)149         ERR_EXIT("open test.txt");150     rio_t rio;151     rio_init(&rio, fd);152 153     char buf[1024] = {0};154     // rio_readn(&rio, buf, 3);155     // printf("%s\n", buf);156 157     while(rio_readline(&rio, buf, sizeof buf) > 0)158     {159         printf("%s", buf);160     }161 162     close(fd);163 164     return 0;165 }

 

 

ReadFile.h

 1 #include "ReadFile.h" 2  3  4 ReadFile::ReadFile(std::string filename) 5 : fd_(-1), 6   filename_(std::move(filename)) 7 { 8  9 }10 11 ReadFile::~ReadFile()12 {13     if(fd_ != -1)14         close();15 }16 17 bool ReadFile::open()18 {19     fd_ = ::open(filename_.c_str(), O_RDONLY);20     if(fd == -1)21         return false;22 23     buffer_.reset(new RobustIO(fd_));24     return true;25 }26 27 void ReadFile::close()28 {29     ::close(fd_);30     fd_ = -1;31 }

ReadFile.cpp

 

 1 #ifndef READ_FILE_H_ 2 #define READ_FILE_H_ 3  4 #include "NonCopyable.h" 5 #include <string> 6  7 class ReadFile : NonCopyable 8 { 9 public:10     ReadFile(std::string filename);11     ~ReadFile();12     bool open();13 14     ssize_t read(char *usrbuf, size_t count);15     ssize_t readn(char *usrbuf, size_t count);16     ssize_t readLine(char *usrbuf, size_t maxlen);17 18     int readInt();   //32 "3211111"19     int32_t readInt32();20     int64_t readInt64();21     string readLine();22 23     void close();24 25 private:26     int fd_;27     std::unique_ptr<RobustIO> buffer_;28     const std::string filename_; //文件名29 };30 31 32 #endif //READ_FILE_H_

缓冲区也封装成类

 1 #ifndef ROBUST_IO_H 2 #define ROBUST_IO_H 3  4 #include "NonCopyable.h" 5 #include <unistd.h> 6  7 class RobustIO : NonCopyable 8 { 9 public:10     RobustIO(int fd);11     ssize_t readn(char *usrbuf, size_t n);12     ssize_t readLine(char *usrbuf, size_t maxlen);13     ssize_t writen(int fd, const void *buf, size_t count);14 private:15     ssize_t read(char *usrbuf, size_t n);16 17     static const int kBufferSize = 65536;18 19     int fd_; //fd20     int cnt_; //缓冲区可用的字节数21     char *ptr_; //指向缓冲区可用的第一个字节22     char buffer_[kBufferSize]; //缓冲区23 };24 25 26 #endif //ROBUST_IO_H
#include "RobustIO.h"#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/wait.h>#include <errno.h>#define ERR_EXIT(m)     do {         perror(m);        exit(EXIT_FAILURE);    }while(0)//const int RobustIO::kBufferSize = 65536;RobustIO::RobustIO(int fd){    fd_ = fd;    cnt_ = 0;    ptr_ = buffer_;    ::memset(buffer_, 0, kBufferSize);}ssize_t RobustIO::read(char *usrbuf, size_t n){    //缓冲区为空时,执行read操作    while(cnt_ <= 0)    {        ssize_t nread = ::read(fd_, buffer_, kBufferSize);        if(nread == -1)        {            if(errno == EINTR)                continue;            return -1;  //ERROR        }        else if(nread == 0)            return 0;        //正常读取        cnt_ = nread;        ptr_ = buffer_; //重置指针    }    //现有库存和用户要求的数量 取较小者    int cnt = (cnt_ < n) ? cnt_ : n;    ::memcpy(usrbuf, ptr_, cnt);    ptr_ += cnt;    cnt_ -= cnt;    return cnt;  //成功读取的字节数}ssize_t RobustIO::readn(char *usrbuf, size_t count){    size_t nleft = count;  //剩余的字节数    ssize_t nread; //用作返回值    char *bufp = (char*)usrbuf; //缓冲区的偏移量    while(nleft > 0)    {        //不再执行read系统调用        nread = this->read(bufp, nleft);        if(nread == -1)        {            if(errno == EINTR)                continue;            return -1; // ERROR        }        else if(nread == 0) //EOF            break;        nleft -= nread;        bufp += nread;    }    return (count - nleft);}ssize_t RobustIO::readLine(char *usrbuf, size_t maxlen){    int i; //计数    int nread;    char *bufp = usrbuf;    char c; //暂存字符    for(i = 0; i < maxlen - 1; ++i)    {        if((nread = this->read(&c, 1)) == -1)            return -1;        else if(nread == 0) //EOF        {            if(i == 0)                return 0;            break;        }        *bufp++ = c; //放入usrbuf        if(c == \n) //碰到换行符直接退出循环            break;     }    *bufp = \0;    return i; //返回读取的字节数 }ssize_t RobustIO::writen(int fd, const void *buf, size_t count){    size_t nleft = count;    ssize_t nwrite;    const char *bufp = (const char*)buf;        while(nleft > 0)    {        nwrite = write(fd, bufp, nleft);        if(nwrite <= 0) // ERROR        {            if(nwrite == -1 && errno == EINTR)                continue;            return -1;        }        nleft -= nwrite;        bufp += nwrite;    }        return count;}

 

封装readn