首页 > 代码库 > 封装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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。