【lesson37】自己设计用户级缓冲区

自己设计用户级缓冲区

因为用户缓冲区在FILE中,所以我们直接模仿C语言提供的文件操作接口,顺便实现缓冲区。
使用文件系统的框架:模仿C语言
在这里插入图片描述
下面就是一步一步实现具体的函数。

简易MyFILE_的结构

#define NUM 1024    
    
struct MyFILE_ {    
    int fd;//文件描述符fd    
    char buffer[NUM];//用户级缓冲区    
    int end; //当前缓冲区的结尾    
};

fopen_的实现

typedef struct MyFILE_ MyFILE;

MyFILE* fopen_(const char* pathname, const char* mode)
{
    assert(pathname);
    assert(mode);

    MyFILE* fp = NULL;

    if (strcmp(mode, "w") == 0)
    {
      int fd = open(pathname,O_WRONLY | O_CREAT | O_TRUNC,0666);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "w+") == 0)
    {
      int fd = open(pathname,O_RDWR | O_CREAT | O_TRUNC,0666);
      if(fd > 0)
      {                                                                                                                                                                 
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "r") == 0)
    {
      int fd = open(pathname,O_RDONLY);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "r+") == 0)
    {
      int fd = open(pathname,O_RDWR);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "a") == 0)
    {
      int fd = open(pathname,O_WRONLY | O_CREAT | O_APPEND,0666);                                                                                                       
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else if (strcmp(mode, "a+") == 0)
    {
      int fd = open(pathname,O_RDWR | O_CREAT | O_APPEND,0666);
      if(fd > 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd;
      }
    }
    else {
        //什么都不做
    }

    return fp;
}

fputs_的实现

void fputs_(const char* message, MyFILE* fp)
{                                     
   assert(message);           
   assert(fp); 
   strcpy(fp->buffer+fp->end,message);
   fp->end += strlen(message);
                       
   if(fp->fd == 0) 
   {           
     //标准输入                       
     //不做任何操作
   }                                                                                                                                                                    
   else if(fp->fd == 1)               
   {             
     //标准输出
     write(fp->fd,fp->buffer,fp->end);
     fp->end = 0;
   }
   else if(fp->fd == 2)
   {
     //标准错误
     write(fp->fd,fp->buffer,fp->end);
     fp->end = 0;
   }
   else 
   {
     //其它文件
     //不做任何操作
   }
}

fclose_的实现

void fclose_(MyFILE *fp)
{
    assert(fp);
    //关闭文件之前,把缓冲区的所有内容刷新出去
    fflush_(fp);
    close(fp->fd);
    free(fp);
}

fflush_的实现

void fflush_(MyFILE* fp)
{
  assert(fp);
  if(fp->end != 0)
  {
    //将数据写到内核,并不是立马写到磁盘文件中
    write(fp->fd,fp->buffer,fp->end);

    syncfs(fp->fd);//将数据写到磁盘
    fp->end = 0;
  }
}

完整版代码

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <fcntl.h>
  7 #include <assert.h>
  8 #include <stdlib.h>
  9 
 10 #define NUM 1024
 11 
 12 struct MyFILE_ {
 13     int fd;
 14     char buffer[NUM];
 15     int end; //当前缓冲区的结尾
 16 };
 17 
 18 typedef struct MyFILE_ MyFILE;
 19 
 20 MyFILE* fopen_(const char* pathname, const char* mode)
 21 {
 22     assert(pathname);
 23     assert(mode);
 24 
 25     MyFILE* fp = NULL;
 26 
 27     if (strcmp(mode, "w") == 0)
 28     {
 29       int fd = open(pathname,O_WRONLY | O_CREAT | O_TRUNC,0666);                                                                                                    
 30       if(fd > 0)
 31       {
 32         fp = (MyFILE*)malloc(sizeof(MyFILE));
 33         memset(fp,0,sizeof(MyFILE));
 34         fp->fd = fd;
 35       }
 36     }
 37     else if (strcmp(mode, "w+") == 0)
 38     {
 39       int fd = open(pathname,O_RDWR | O_CREAT | O_TRUNC,0666);
 40       if(fd > 0)
 41       {
 42         fp = (MyFILE*)malloc(sizeof(MyFILE));                                                                                                                       
 43         memset(fp,0,sizeof(MyFILE));
 44         fp->fd = fd;
 45       }
 46     }
 47     else if (strcmp(mode, "r") == 0)
 48     {
 49       int fd = open(pathname,O_RDONLY);
 50       if(fd > 0)
 51       {
 52         fp = (MyFILE*)malloc(sizeof(MyFILE));
 53         memset(fp,0,sizeof(MyFILE));
 54         fp->fd = fd;
 55       }
 56     }
 57     else if (strcmp(mode, "r+") == 0)
 58     {
 59       int fd = open(pathname,O_RDWR);
 60       if(fd > 0)
 61       {
 62         fp = (MyFILE*)malloc(sizeof(MyFILE));
 63         memset(fp,0,sizeof(MyFILE));
 64         fp->fd = fd;
 65       }
 66     }
 67     else if (strcmp(mode, "a") == 0)
 68     {
 69       int fd = open(pathname,O_WRONLY | O_CREAT | O_APPEND,0666);
 70       if(fd > 0)
 71       {
 72         fp = (MyFILE*)malloc(sizeof(MyFILE));                                                                                                                       
 73         memset(fp,0,sizeof(MyFILE));
 74         fp->fd = fd;
 75       }
 76 
 77     }
 78     else if (strcmp(mode, "a+") == 0)
 79     {
 80       int fd = open(pathname,O_RDWR | O_CREAT | O_APPEND,0666);
 81       if(fd > 0)
 82       {
 83         fp = (MyFILE*)malloc(sizeof(MyFILE));
 84         memset(fp,0,sizeof(MyFILE));
 85         fp->fd = fd;
 86       }
 87 
 88     }
 89     else {
 90         //什么都不做
 91     }
 92 
 93     return fp;
 94 }
 95 
 96 void fputs_(const char* message, MyFILE* fp)
 97 {
 98    assert(message);
 99    assert(fp);
100    strcpy(fp->buffer+fp->end,message);
101    fp->end += strlen(message);
102 
103    if(fp->fd == 0)
104    {
105      //标准输入                                                                                                                                                     
106      //不做任何操作
107    }
108    else if(fp->fd == 1)
109    {
110      //标准输出
111      write(fp->fd,fp->buffer,fp->end);
112      fp->end = 0;
113    }
114    else if(fp->fd == 2)
115    {
116      //标准错误
117      write(fp->fd,fp->buffer,fp->end);
118      fp->end = 0;
119    }
120    else 
121    {
122      //其它文件
123      //不做任何操作
124    }
125 }
126 
127 
128 void fflush_(MyFILE* fp)
129 {
130   assert(fp);
131   if(fp->end != 0)
132   {
133     //将数据写到内核,并不是立马写到磁盘文件中
134     write(fp->fd,fp->buffer,fp->end);
135 
136     syncfs(fp->fd);//将数据写到磁盘
137     fp->end = 0;
138   }                                                                                                                                                                 
139 }
140 
141 void fclose_(MyFILE* fp)
142 {
143   assert(fp);
144 
145   fflush_(fp);
146   close(fp->fd);
147   free(fp);
148 }
149 
150 int main()
151 {
152     MyFILE* fp = fopen_("./log.txt", "w");
153     if (fp == NULL)
154     {
155         printf("open file error");
156         return 1;
157     }
158     else 
159     {
160 
161         const char* s = "hello world\n";
162         fputs_(s, fp);
163 
164 
165         fclose_(fp);
166     }
167 
168     return 0;
169 }


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值