资源描述
模拟一个简单二级文件管理系统
36
2020年4月19日
文档仅供参考
模拟一个简单二级文件管理系统
设计目的:经过具体的文件存储空间的管理、文件的物理结构、目录结构和文件操作的实现,加深对文件系统内部功能和实现过程的理解。
设计内容:模拟一个简单二级文件管理系统
一、实验内容描述
1 实验目标
本实验的目的是经过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现.
2 实验要求
为DOS系统设计一个简单的二级文件系统.要求做到以下几点:
①能够实现下列命令:
login 用户登录
dir 列文件目录
create 创立文件
delete 删除文件
open 打开文件
close 关闭文件
read 读文件
write 写文件
②列目录时要列出文件名、物理地址、保护码和文件长度.
③源文件能够进行读写保护.
二、程序主要内容
1设计思路
程序中要求每个用户在登陆后才可对其拥有的文件进行操作,用户对于其它用户的文件无操作权.文件操作包括浏览、创立、删除、打开、关闭、阅读、写入、修改模式.其它操作包括新建用户、帮助、用户登入、用户登出、退出系统.
在程序文件夹下有个名为“file”的系统根目录,此目录下包括:一个名为“mfd”的文件,记录所有注册过的帐号及密码;用户文件,以用户名作为文件名,内容为其拥有的文件名及属性;一个名为“keiji”的文件夹.“keiji”文件夹中包括:“file.p”指针文件,记录所有已用的物理地址;一些以物理地址为名的文件,内容为文件内容.
2 数据结构
file结构体系统文件数据结构:
fpaddrint,文件的物理地址、flengthint,文件长度、fmodeint,文件模式 0.只读;1.可写;2.可读写;3.保护、 fname[]char,文件名;
filemode结构体文件状态数据结构:
isopenint,文件当前状态,0.关闭;1.打开、modeint,文件模式 0.只读;1.可写;2.可读写;3.初始化;
user结构体用户信息数据结构:
uname[]char,用户名、upassword[]char,用户密码;
userfile结构体用户文件数据结构:
uname[]char,用户名、ufile[]file,用户拥有的文件数组.
.......
[cpp] view plaincopyprint?
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <conio.h>
4. #include <time.h>
5. #include <string.h>
6. #define MaxUser 100 //定义最大MDF主目录文件
7. #define MaxDisk 512*1024 //模拟最大磁盘空间
8. #define commandAmount 12 //对文件操作的指令数
9. //存储空间管理有关结构体和变量
10. char disk[MaxDisk]; //模拟512K的磁盘存储空间
11. typedef struct distTable //磁盘块结构体
12. {
13. int maxlength;
14. int start;
15. int useFlag;
16. distTable *next;
17. }diskNode;
18. diskNode *diskHead;
19. struct fileTable //文件块结构体
20. {
21. char fileName[10];
22. int strat; //文件在磁盘存储空间的起始地址
23. int length; //文件内容长度
24. int maxlength; //文件的最大长度
25. char fileKind[3]; //文件的属性——读写方式
26. struct tm *timeinfo;
27. bool openFlag; //判断是否有进程打开了该文件
28. //fileTable *next;
29. };
30.
31. //两级目录结构体
32. typedef struct user_file_directory //用户文件目录文件UFD
33. {
34. //char fileName[10];
35. fileTable *file;
36. user_file_directory *next;
37. }UFD;
38. //UFD *headFile;
39. typedef struct master_file_directory //主文件目录MFD
40. {
41. char userName[10];
42. char password[10];
43. UFD *user;
44. }MFD;
45. MFD userTable[MaxUser];
46. int used=0; //定义MFD目录中用已有的用户数
47.
48. //文件管理
49. void fileCreate(char fileName[],int length,char fileKind[]); //创立文件
50. void fileWrite(char fileName[]); //写文件
51. void fileCat(char fileName[]); //读文件
52. void fileRen(char fileName[],char rename[]); //重命名文件
53. void fileFine(char fileName[]); //查询文件
54. void fileDir(char UserName[]); //显示某一用户的所有文件
55. void fileClose(char fileName[]); //关闭已打开的文件
56. void fileDel(char fileName[]); //删除文件
57. void chmod(char fileName[],char kind[]); //修改文件的读写方式
58. int requestDist(int &startPostion,int maxLength); //磁盘分配查询
59. void initDisk(); //初始化磁盘
60. void freeDisk(int startPostion); //磁盘空间释放
61. void diskShow(); //显示磁盘使用情况
62.
63. //用户管理
64. void userCreate();
65. int login();
66. int userID=-1; //用户登录的ID号,值为-1时表示没有用户登录
67.
68. int main()
69. {
70. char order[commandAmount][10];
71. strcpy(order[0],"create");
72. strcpy(order[1],"rm");
73. strcpy(order[2],"cat");
74. strcpy(order[3],"write");
75. strcpy(order[4],"fine");
76. strcpy(order[5],"chmod");
77. strcpy(order[6],"ren");
78. strcpy(order[7],"dir");
79. strcpy(order[8],"close");
80. strcpy(order[9],"return");
81. strcpy(order[10],"exit");
82. strcpy(order[11],"df");
83. char command[50],command_str1[10],command_str2[10],command_str3[5],command_str4[3];
84. int i,k,j;
85. int length;
86. initDisk(); //初始化磁盘
87. for(i=0;i<MaxUser;i++) //初始化用户UFD目录文件的头指针
88. {
89. userTable[i].user=(UFD *)malloc(sizeof(UFD));
90. userTable[i].user->next=NULL;
91. }
92. while(1)
93. {
94. printf("********************************************/n");
95. printf(" 1、Creat user/n");
96. printf(" 2、login/n");
97. printf("********************************************/n");
98. printf("Please chooce the function key:>");
99. int choice;
100. scanf("%d",&choice);
101. if(choice==1) userCreate();
102. else if(choice==2) userID=login();
103. else printf("您的输入有误,请重新选择/n");
104. while(userID!=-1)
105. {
106. fflush(stdin);
107. printf("———————————————————————————————————————/n");
108. printf(" create-创立 格式:create a1 1000 rw,将创立名为a1,长度为1000字节可读可写的文件/n");
109. printf(" rm-删除 格式:rm a1,将删除名为a1的文件/n");
110. printf(" cat-查看文件内容 格式:cat a1,显示a1的内容/n");
111. printf(" write-写入 格式:write a1/n");
112. printf(" fine-查询 格式:fine a1 ,将显示文件 a1的属性/n");
113. printf(" chmod-修改 格式:chmod a1 r,将文件a1的权限改为只读方式/n");
114. printf(" ren-重命名 格式:ren a1 b1 ,将a1改名为b1/n");
115. printf(" dir-显示文件 格式:dir aaa,将显示aaa用户的所有文件/n");
116. printf(" df-显示磁盘空间使用情况 格式:df/n");
117. printf(" close-关闭文件 格式:close a1,将关闭文件a1/n");
118. printf(" return-退出用户,返回登录界面/n");
119. printf(" exit-退出程序/n");
120. printf("————————————————————————————————————————/n");
121. printf("please imput your command:>");
122. gets(command);
123. int select;
124. for(i=0;command[i]!=' '&&command[i]!='/0';i++) //command_str1字符串存储命令的操作类型
125. command_str1[i]=command[i];
126. k=i;
127. command_str1[k]='/0';
128. for(i=0;i<commandAmount;i++)
129. {
130. if(!strcmp(command_str1,order[i]))
131. {
132. select=i;
133. break;
134. }
135. }
136. if(i==commandAmount)
137. {
138. printf("您输入的命令有误,请重新输入/n");
139. continue;
140. }
141. for(i=k+1,k=0;command[i]!=' '&&command[i]!='/0';i++,k++) //commmand_str2字符串存储文件名或用户名
142. command_str2[k]=command[i];
143. command_str2[k]='/0';
144. k=i;
145. switch(select)
146. {
147. case 0:for(i=k+1,k=0;command[i]!=' ';i++,k++)
148. command_str3[k]=command[i];
149. command_str3[k]='/0';
150. k=i;
151. j=1;
152. length=0; //初始化文件长度
153. for(i=strlen(command_str3)-1;i>=0;i--) //把字符串转换为十进制
154. {
155. length+=(command_str3[i]-48)*j;
156. j*=10;
157. }
158. for(i=k+1,k=0;command[i]!=' '&&command[i]!='/0';i++,k++)
159. command_str4[k]=command[i];
160. command_str4[k]='/0';
161. fileCreate(command_str2,length,command_str4);break;
162. case 1:fileDel(command_str2);break;
163. case 2:fileCat(command_str2);break;
164. case 3:
165. fileWrite(command_str2);break;
166. case 4:fileFine(command_str2);break;
167. case 5:for(i=k+1,k=0;command[i]!=' '&&command[i]!='/0';i++,k++)
168. command_str3[k]=command[i];
169. command_str3[k]='/0';
170. chmod(command_str2,command_str3);break;
171. case 6:for(i=k+1,k=0;command[i]!='/0';i++,k++)
172. command_str3[k]=command[i];
173. command_str3[k]='/0';
174. fileRen(command_str2,command_str3);break;
175. case 7:fileDir(command_str2);break;
176. case 8:fileClose(command_str2);break;
177. case 9:UFD *p;
178. for(p=userTable[userID].user->next;p!=NULL;p=p->next) //退出用户之前关闭所有打的文件
179. if(p->file->openFlag)
180. p->file->openFlag=false;
181. system("cls");
182. userID=-1;break;
183. case 10:exit(0);break;
184. case 11:diskShow();break;
185. }
186. }
187. }
188. return 0;
189. }
190.
191. void userCreate()
192. {
193. char c;
194. char userName[10];
195. int i;
196. if(used<MaxUser)
197. {
198. printf("请输入用户名:");
199. for(i=0;c=getch();i++)
200. {
201. if(c==13) break;
202. else
203. userName[i]=c;
204. printf("%c",c);
205. }
206. userName[i]='/0';
207. for(i=0;i<used;i++)
208. {
209. if(!strcmp(userTable[i].userName,userName))
210. {
211. printf("/n");
212. printf("该用户名已存在,创立用户失败/n");
213. system("pause");
214. return;
215. }
216. }
217. strcpy(userTable[used].userName,userName);
218. printf("/n");
219. printf("请输入密码:");
220. for(i=0;c=getch();i++)
221. {
222. if(c==13) break;
223. else
224. userTable[used].password[i]=c;
225. printf("*");
226. }
227. userTable[userID].password[i]='/0';
228. printf("/n");
229. printf("创立用户成功/n");
230. used++;
231. system("pause");
232. }
233. else
234. {
235. printf("创立用户失败,用户已达到上限/n");
236. system("pause");
237. }
238. fflush(stdin);
239. }
240.
241. int login()
242. {
243. char name[10],psw[10];
244. char c;
245. int i,times;
246. printf("请输入用户名:");
247. for(i=0;c=getch();i++)
248. {
249. if(c==13) break;
250. else
251. name[i]=c;
252. printf("%c",c);
253. }
254. name[i]='/0';
255. for(i=0;i<used;i++)
256. {
257. if(!strcmp(userTable[i].userName,name))
258. break;
259. }
260. if(i==used)
261. {
262. printf("/n您输入的用户名不存在/n");
263. system("pause");
264. return -1;
265. }
266. for(times=0;times<3;times++)
267. {
268. memset(psw,'/0',sizeof(psw));
269. printf("/n请输入密码:");
270. for(i=0;c=getch();i++)
271. {
272. if(c==13) break;
273. else
274. psw[i]=c;
275. printf("*");
276. }
277. printf("/n");
278. for(i=0;i<used;i++)
279. {
280. if(!strcmp(psw,userTable[i].password))
281. {
282. printf("用户登录成功/n");
283. system("pause");
284. break;
285. }
286. }
287. if(i==used)
288. {
289. printf("您输入的密码错误,您还有%d次输入机会/n",2-times);
290. if(times==2) exit(0);
291. }
292. else break;
293. }
294. fflush(stdin);
295. return i;
296. }
297.
298. void initDisk()
299. {
300. diskHead=(diskNode *)malloc(sizeof(diskNode));
301. diskHead->maxlength=MaxDisk;
302. diskHead->useFlag=0;
303. diskHead->start=0;
304. diskHead->next=NULL;
305. }
306. int requestDist(int &startPostion,int maxLength)
307. {
308. int flag=0; //标记是否分配成功
309. diskNode *p,*q,*temp;
310. p=diskHead;
311. while(p)
312. {
313. if(p->useFlag==0&&p->maxlength>maxLength)
314. {
315. startPostion=p->start;
316. q=(diskNode *)malloc(sizeof(diskNode));
317. q->start=p->start;
318. q->maxlength=maxLength;
319. q->useFlag=1;
320. q->next=NULL;
321. diskHead->start=p->start+maxLength;
322. diskHead->maxlength=p->maxlength-maxLength;
323. flag=1;
324. temp=p;
325. if(diskHead->next==NULL) diskHead->next=q;
326. else
327. {
328. while(temp->next) temp=temp->next;
329. temp->next=q;
330. }
331. break;
332. }
333. p=p->next;
334. }
335. return flag;
336. }
337.
338. void fileCreate(char fileName[],int length,char fileKind[])
339. {
340. //int i,j;
341. time_t rawtime;
342. int startPos;
343. UFD *fileNode,*p;
344. for(p=userTable[userID].user->next;p!=NULL;p=p->next)
345. {
346. if(!strcmp(p->file->fileName,fileName))
347. {
348. printf("文件重名,创立文件失败/n");
349. system("pause");
350. return;
351. }
352. }
353. if(requestDist(startPos,length))
354. {
355. fileNode=(UFD *)malloc(sizeof(UFD));
356. fileNode->file=(fileTable *)malloc(sizeof(fileTable)); //这一步必不可少,因为fileNode里面的指针也需要申请地址,否则fileNode->file指向会出错
357. strcpy(fileNode->file->fileName,fileName);
358. strcpy(fileNode->file->fileKind,fileKind);
359. fileNode->file->maxlength=length;
360. fileNode->file->strat=startPos;
361. fileNode->file->openFlag=false;
362. time(&rawtime);
363. fileNode->file->timeinfo=localtime(&rawtime);
364. fileNode->next=NULL;
365. if(userTable[userID].user->next==NULL)
366. userTable[userID].user->next=fileNode;
367. else
368. {
369. p=userTable[userID].user->next;
370. while(p->next) p=p->next;
371. p->next=fileNode;
372. }
373. printf("创立文件成功/n");
374. system("pause");
375. }
376. else
377. {
378. printf("磁盘空间已满或所创立文件超出磁盘空闲容量,磁盘空间分配失败/n");
379. system("pause");
380. }
381. }
382.
383. void freeDisk(int startPostion)
384. {
385. diskNode *p;
386. for(p=diskHead;p!=NULL;p=p->next)
387. {
388. if(p->start==startPostion)
389. break;
390. }
391. p->useFlag=false;
392. }
393.
394. void fileDel(char fileName[])
395. {
396. UFD *p,*q,*temp;
397. q=userTable[userID].user;
398. p=q->next;
399. while(p)
400. {
401. if(!strcmp(p->file->fileName,fileName)) break;
402. else
403. {
404. p=p->next;
405. q=q->next;
406. }
407. }
408. if(p)
409. {
410. if(p->file->openFlag!=true) //先判断是否有进程打开该文件
411. {
412. temp=p;
413. q->next=p->next;
414. freeDisk(temp->file->strat); //磁盘空间回收
415. free(temp);
416. printf("文件删除成功/n");
417. system("pause");
418. }
419. else
420. {
421. printf("该文件已被进程打开,删除失败/n");
422. system("pause");
423. }
424. }
425. else
426. {
427. printf("没有找到该文件,请检查输入的文件名是否正确/n");
428. system("pause");
429. }
430. }
431.
432. void fileCat(char fileName[])
433. {
434. int startPos,length;
435. int k=0;
436. UFD *p,*q;
437. q=userTable[userID].user;
438. for(p=q->next;p!=NULL;p=p->next)
439. {
440. if(!strcmp(p->file->fileName,fileName))
441. break;
442. }
443. if(p)
444. {
445. startPos=p->file->strat;
446. length=p->file->length;
447. p->file->openFlag=true; //文件打开标记
448. printf("*****************************************************/n");
449. for(int i=startPos;k<length;i++,k++)
450. {
451. if(i%50==0) printf("/n"); //一行大于50个字符换行
452. printf("%c",disk[i]);
453. }
454. printf("/n/n*****************************************************/n");
455. printf("%s已被read进程打开,请用close命令将其关闭/n",p->file->fileName);
456. system("pause");
457. }
458. else
459. {
460. printf("没有找到该文件,请检查输入的文件名是否正确/n");
461. system("pause");
462. }
463. }
464.
465. void fileWrite(char fileName[])
466. {
467. UFD *p,*q;
468. q=userTable[userID].user;
469. int i,k,startPos;
470. for(p=q->next;p!=NULL;p=p->next)
471. {
472. if(!strcmp(p->file->fileName,fileName))
473. break;
474. }
475. if(p)
476. {
477. if(!strcmp(p->file->fileKind,"r")) //判断文件类型
478. {
479. printf("该文件是只读文件,写入失败/n");
480. system("pause");
481. return;
482. }
483. char str[500];
484. printf("please input content:/n");
485. gets(str);
486. startPos=p->file->strat;
487. p->file->openFlag=true; //文件打开标记
488. p->file->length=strlen(str);
489. if(p->file->length>p->file->maxlength)
490. {
491. printf("写入字符串长度大于该文件的总长度,写入失败/n");
492. system("pause");
493. return;
494. }
495. for(i=startPos,k=0;k<(int)strlen(str);i++,k++)
496. disk[i]=str[k];
497. printf("文件写入成功,请用close命令将该文件关闭/n");
498. system("pause");
499. }
500. else
501. {
502. printf("没有找到该文件,请检查输入的文件名是否正确/n");
503. system("pause");
504. }
505. }
506.
507. void fileFine(char fileName[])
508. {
509. UFD *p,*q;
510. q=userTable[userID].user;
511. for(p=q->next;p!=NULL;p=p->next)
512. {
513. if(!strcmp(p->file->fileName,fileName))
514. break;
515. }
516. if(p)
517. {
518. printf("********************************************/n");
519. printf("文件名:%s/n",p->file->fileName);
520. printf("文件长度:%d/n",p->file->maxlength);
521. printf("文件在存储空间的起始地址:%d/n",p->file->strat);
522. printf("文件类型:%s/n",p->file->fileKind);
523. printf("创立时间:%s/n",asctime(p->file->timeinfo));
524. printf("********************************************/n");
525. system("pause");
526. }
527. else
528. {
529. printf("没有找到该文件,请检查输入的文件名是否正
展开阅读全文