封装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) //EOF 106 { 107 if(i == 0) 108 return 0; 109 break; 110 } 111 112 *bufp++ = c; //放入usrbuf 113 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) // ERROR 131 { 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_; //fd 20 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; }