封装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;
}

 

posted @ 2014-10-11 17:27  tilly_chang  阅读(235)  评论(0编辑  收藏  举报