文章目录
- 自己设计用户级缓冲区
- 简易MyFILE_的结构
- fopen_的实现
- fputs_的实现
- fclose_的实现
- fflush_的实现
- 完整版代码
自己设计用户级缓冲区
因为用户缓冲区在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 }