【操作系统】C语言编写的FAT16文件系统

这是操作系统的期末课程设计作业之一,主要功能是在物理内存中虚拟出一个1M大小的FAT16的文件系统,然后把它读入内存中,进行具体的文件操作,具体的实用性不大,主要目的是为了练习C语言,帮助理解文件系统的特点,代码如下:

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #define BLOCKSIZE 1024  // 磁盘块大小
  6. #define SIZE 1024000  // 虚拟磁盘空间大小
  7. #define END 65535  // FAT中的文件结束标志
  8. #define FREE 0  // FAT中盘块空闲标志
  9. #define ROOTBLOCKNUM 2  // 根目录区所占盘块数
  10. #define MAXOPENFILE 10  // 最多同时打开文件个数t
  11. #define MAXTEXT 10000
  12. /* 文件控制块 */
  13. typedef struct FCB
  14. {
  15. char filename[8];  // 文件名
  16. char exname[3];  // 文件扩展名
  17. unsigned char attribute;  // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件
  18. unsigned short time;  // 文件创建时间
  19. unsigned short date;  // 文件创建日期
  20. unsigned short first;  // 文件起始盘块号
  21. unsigned long length;  // 文件长度
  22. char free;  // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配
  23. }fcb;
  24. /* 文件分配表 */
  25. typedef struct FAT
  26. {
  27. unsigned short id;  // 磁盘块的状态(空闲的,最后的,下一个)
  28. }fat;
  29. /* 用户打开文件表 */
  30. typedef struct USEROPEN
  31. {
  32. char filename[8];  // 文件名
  33. char exname[3];  // 文件扩展名
  34. unsigned char attribute;  // 文件属性字段,值为0时表示目录文件,值为1时表示数据文件
  35. unsigned short time;  // 文件创建时间
  36. unsigned short date;  // 文件创建日期
  37. unsigned short first;  // 文件起始盘块号
  38. unsigned long length;  // 文件长度(对数据文件是字节数,对目录文件可以是目录项个数)
  39. char free;  // 表示目录项是否为空,若值为0,表示空,值为1,表示已分配
  40. unsigned short dirno;  // 相应打开文件的目录项在父目录文件中的盘块号
  41. int diroff;  // 相应打开文件的目录项在父目录文件的dirno盘块中的目录项序号
  42. char dir[80];  // 相应打开文件所在的目录名,这样方便快速检查出指定文件是否已经打开
  43. int father;  // 父目录在打开文件表项的位置
  44. int count;  // 读写指针在文件中的位置,文件的总字符数
  45. char fcbstate;  // 是否修改了文件的FCB的内容,如果修改了置为1,否则为0
  46. char topenfile;  // 表示该用户打开表项是否为空,若值为0,表示为空,否则表示已被某打开文件占据
  47. }useropen;
  48. /* 引导块 */
  49. typedef struct BLOCK0
  50. {
  51. char magic[10];  // 文件系统魔数
  52. char information[200];  // 存储一些描述信息,如磁盘块大小、磁盘块数量、最多打开文件数等
  53. unsigned short root;  // 根目录文件的起始盘块号
  54. unsigned char *startblock;  // 虚拟磁盘上数据区开始位置
  55. }block0;
  56. unsigned char *myvhard;  // 指向虚拟磁盘的起始地址
  57. useropen openfilelist[MAXOPENFILE];  // 用户打开文件表数组
  58. int curdir;  // 用户打开文件表中的当前目录所在打开文件表项的位置
  59. char currentdir[80];  // 记录当前目录的目录名(包括目录的路径)
  60. unsigned char* startp;  // 记录虚拟磁盘上数据区开始位置
  61. char myfilename[] = "myfilesys";//文件系统的文件名
  62. void startsys();  // 进入文件系统
  63. void my_format();  // 磁盘格式化
  64. void my_cd(char *dirname);  // 更改当前目录
  65. void my_mkdir(char *dirname);  // 创建子目录
  66. void my_rmdir(char *dirname);  // 删除子目录
  67. void my_ls();  // 显示目录
  68. void my_create (char *filename);  // 创建文件
  69. void my_rm(char *filename);  // 删除文件
  70. int my_open(char *filename);  // 打开文件
  71. int my_close(int fd);  // 关闭文件
  72. int my_write(int fd);  // 写文件
  73. int do_write(int fd, char *text, int len, char wstyle);  // 实际写文件
  74. int my_read (int fd, int len);  // 读文件
  75. int do_read (int fd, int len,char *text);  // 实际读文件
  76. void my_exitsys();  // 退出文件系统
  77. unsigned short findblock();  // 寻找空闲盘块
  78. int findopenfile();  // 寻找空闲文件表项
  79. void startsys()
  80. {
  81. FILE *fp;
  82. unsigned char buf[SIZE];
  83. fcb *root;
  84. int i;
  85. myvhard = (unsigned char *)malloc(SIZE);//申请虚拟磁盘空间
  86. memset(myvhard, 0, SIZE);//将myvhard中前SIZE个字节用 0 替换并返回 myvhard
  87. if((fp = fopen(myfilename, "r")) != NULL)
  88. {
  89. fread(buf, SIZE, 1, fp);//将二进制文件读取到缓冲区
  90. fclose(fp);//关闭打开的文件,缓冲区数据写入文件,释放系统提供文件资源
  91. if(strcmp(((block0 *)buf)->magic, "10101010"))//判断开始的8个字节内容是否为文件系统魔数
  92. {
  93. printf("myfilesys is not exist,begin to creat the file...\n");
  94. my_format();
  95. }
  96. else
  97. {
  98. for(i = 0; i < SIZE; i++)
  99. myvhard[i] = buf[i];
  100. }
  101. }
  102. else
  103. {
  104. printf("myfilesys is not exist,begin to creat the file...\n");
  105. my_format();
  106. }
  107. root = (fcb *)(myvhard + 5 * BLOCKSIZE);
  108. strcpy(openfilelist[0].filename, root->filename);
  109. strcpy(openfilelist[0].exname, root->exname);
  110. openfilelist[0].attribute = root->attribute;
  111. openfilelist[0].time = root->time;
  112. openfilelist[0].date = root->date;
  113. openfilelist[0].first = root->first;
  114. openfilelist[0].length = root->length;
  115. openfilelist[0].free = root->free;
  116. openfilelist[0].dirno = 5;
  117. openfilelist[0].diroff = 0;
  118. strcpy(openfilelist[0].dir, "\\root\\");
  119. openfilelist[0].father = 0;
  120. openfilelist[0].count = 0;
  121. openfilelist[0].fcbstate = 0;
  122. openfilelist[0].topenfile = 1;
  123. for(i = 1; i < MAXOPENFILE; i++)
  124. openfilelist[i].topenfile = 0;
  125. curdir = 0;
  126. strcpy(currentdir, "\\root\\");
  127. startp = ((block0 *)myvhard)->startblock;
  128. }
  129. void my_format()
  130. {
  131. FILE *fp;
  132. fat *fat1, *fat2;
  133. block0 *blk0;
  134. time_t now;
  135. struct tm *nowtime;
  136. fcb *root;
  137. int i;
  138. blk0 = (block0 *)myvhard;
  139. fat1 = (fat *)(myvhard + BLOCKSIZE);
  140. fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
  141. root = (fcb *)(myvhard + 5 * BLOCKSIZE);
  142. strcpy(blk0->magic, "10101010");
  143. strcpy(blk0->information, "My FileSystem Ver 1.0 \n Blocksize=1KB Whole size=1000KB Blocknum=1000 RootBlocknum=2\n");
  144. blk0->root = 5;
  145. blk0->startblock = (unsigned char *)root;
  146. for(i = 0; i < 5; i++)
  147. {
  148. fat1->id = END;
  149. fat2->id = END;
  150. fat1++;
  151. fat2++;
  152. }
  153. fat1->id = 6;
  154. fat2->id = 6;
  155. fat1++;
  156. fat2++;
  157. fat1->id = END;
  158. fat2->id = END;
  159. fat1++;
  160. fat2++;
  161. for(i = 7; i < SIZE / BLOCKSIZE; i++)
  162. {
  163. fat1->id = FREE;
  164. fat2->id = FREE;
  165. fat1++;
  166. fat2++;
  167. }
  168. now = time(NULL);
  169. nowtime = localtime(&now);
  170. strcpy(root->filename, ".");
  171. strcpy(root->exname, "");
  172. root->attribute = 0x28;
  173. root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
  174. root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
  175. root->first = 5;
  176. root->length = 2 * sizeof(fcb);
  177. root->free = 1;
  178. root++;
  179. now = time(NULL);
  180. nowtime = localtime(&now);
  181. strcpy(root->filename, "..");
  182. strcpy(root->exname, "");
  183. root->attribute = 0x28;
  184. root->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
  185. root->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
  186. root->first = 5;
  187. root->length = 2 * sizeof(fcb);
  188. root->free = 1;
  189. fp = fopen(myfilename, "w");
  190. fwrite(myvhard, SIZE, 1, fp);
  191. fclose(fp);
  192. }
  193. void my_cd(char *dirname)
  194. {
  195. char *dir;
  196. int fd;
  197. dir = strtok(dirname, "\\");//分解字符串为一组字符串。dirname为要分解的字符串,"\\"为分隔符字符串
  198. if(strcmp(dir, ".") == 0)
  199. return;
  200. else if(strcmp(dir, "..") == 0)
  201. {
  202. if(curdir)
  203. curdir = my_close(curdir);
  204. return;
  205. }
  206. else if(strcmp(dir, "root") == 0)
  207. {
  208. while(curdir)
  209. curdir = my_close(curdir);
  210. dir = strtok(NULL, "\\");
  211. }
  212. while(dir)
  213. {
  214. fd = my_open(dir);
  215. if(fd != -1)
  216. curdir = fd;
  217. else
  218. return;
  219. dir = strtok(NULL, "\\");
  220. }
  221. }
  222. void my_mkdir(char *dirname)
  223. {
  224. fcb *fcbptr;
  225. fat *fat1, *fat2;
  226. time_t now;
  227. struct tm *nowtime;
  228. char text[MAXTEXT];
  229. unsigned short blkno;
  230. int rbn, fd, i;
  231. fat1 = (fat *)(myvhard + BLOCKSIZE);
  232. fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
  233. openfilelist[curdir].count = 0;
  234. rbn = do_read(curdir, openfilelist[curdir].length, text);
  235. fcbptr = (fcb *)text;
  236. for(i = 0; i < rbn / sizeof(fcb); i++)//在当前目录下找,是否有重名目录
  237. {
  238. if(strcmp(fcbptr->filename, dirname) == 0 && strcmp(fcbptr->exname, "") == 0)
  239. {
  240. printf("Error,the dirname is already exist!\n");
  241. return;
  242. }
  243. fcbptr++;
  244. }
  245. fcbptr = (fcb *)text;
  246. for(i = 0; i < rbn / sizeof(fcb); i++)
  247. {
  248. if(fcbptr->free == 0)
  249. break;
  250. fcbptr++;
  251. }
  252. blkno = findblock();//寻找空闲盘块
  253. if(blkno == -1)
  254. return;
  255. (fat1 + blkno)->id = END;
  256. (fat2 + blkno)->id = END;
  257. now = time(NULL);
  258. nowtime = localtime(&now);
  259. strcpy(fcbptr->filename, dirname);
  260. strcpy(fcbptr->exname, "");
  261. fcbptr->attribute = 0x30;
  262. fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
  263. fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
  264. fcbptr->first = blkno;
  265. fcbptr->length = 2 * sizeof(fcb);
  266. fcbptr->free = 1;
  267. openfilelist[curdir].count = i * sizeof(fcb);
  268. do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
  269. fd = my_open(dirname);//建立新目录的'.','..'目录
  270. if(fd == -1)
  271. return;
  272. fcbptr = (fcb *)malloc(sizeof(fcb));
  273. now = time(NULL);
  274. nowtime = localtime(&now);
  275. strcpy(fcbptr->filename, ".");
  276. strcpy(fcbptr->exname, "");
  277. fcbptr->attribute = 0x28;
  278. fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
  279. fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
  280. fcbptr->first = blkno;
  281. fcbptr->length = 2 * sizeof(fcb);
  282. fcbptr->free = 1;
  283. do_write(fd, (char *)fcbptr, sizeof(fcb), 2);
  284. now = time(NULL);
  285. nowtime = localtime(&now);
  286. strcpy(fcbptr->filename, "..");
  287. strcpy(fcbptr->exname, "");
  288. fcbptr->attribute = 0x28;
  289. fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
  290. fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
  291. fcbptr->first = blkno;
  292. fcbptr->length = 2 * sizeof(fcb);
  293. fcbptr->free = 1;
  294. do_write(fd, (char *)fcbptr, sizeof(fcb), 2);
  295. free(fcbptr);
  296. my_close(fd);
  297. fcbptr = (fcb *)text;
  298. fcbptr->length = openfilelist[curdir].length;
  299. openfilelist[curdir].count = 0;
  300. do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
  301. openfilelist[curdir].fcbstate = 1;
  302. }
  303. void my_rmdir(char *dirname)
  304. {
  305. fcb *fcbptr,*fcbptr2;
  306. fat *fat1, *fat2, *fatptr1, *fatptr2;
  307. char text[MAXTEXT], text2[MAXTEXT];
  308. unsigned short blkno;
  309. int rbn, rbn2, fd, i, j;
  310. fat1 = (fat *)(myvhard + BLOCKSIZE);
  311. fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
  312. if(strcmp(dirname, ".") == 0 || strcmp(dirname, "..") == 0)
  313. {
  314. printf("Error,can't remove this directory.\n");
  315. return;
  316. }
  317. openfilelist[curdir].count = 0;
  318. rbn = do_read(curdir, openfilelist[curdir].length, text);
  319. fcbptr = (fcb *)text;
  320. for(i = 0; i < rbn / sizeof(fcb); i++)//查找要删除的目录
  321. {
  322. if(strcmp(fcbptr->filename, dirname) == 0 && strcmp(fcbptr->exname, "") == 0)
  323. break;
  324. fcbptr++;
  325. }
  326. if(i == rbn / sizeof(fcb))
  327. {
  328. printf("Error,the directory is not exist.\n");
  329. return;
  330. }
  331. fd = my_open(dirname);
  332. rbn2 = do_read(fd, openfilelist[fd].length, text2);
  333. fcbptr2 = (fcb *)text2;
  334. for(j = 0; j < rbn2 / sizeof(fcb); j++)//判断要删除目录是否为空
  335. {
  336. if(strcmp(fcbptr2->filename, ".") && strcmp(fcbptr2->filename, "..") && strcmp(fcbptr2->filename, ""))
  337. {
  338. my_close(fd);
  339. printf("Error,the directory is not empty.\n");
  340. return;
  341. }
  342. fcbptr2++;
  343. }
  344. blkno = openfilelist[fd].first;
  345. while(blkno != END)
  346. {
  347. fatptr1 = fat1 + blkno;
  348. fatptr2 = fat2 + blkno;
  349. blkno = fatptr1->id;
  350. fatptr1->id = FREE;
  351. fatptr2->id = FREE;
  352. }
  353. my_close(fd);
  354. strcpy(fcbptr->filename, "");
  355. fcbptr->free = 0;
  356. openfilelist[curdir].count = i * sizeof(fcb);
  357. do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
  358. openfilelist[curdir].fcbstate = 1;
  359. }
  360. void my_ls()
  361. {
  362. fcb *fcbptr;
  363. char text[MAXTEXT];
  364. int rbn, i;
  365. openfilelist[curdir].count = 0;
  366. rbn = do_read(curdir, openfilelist[curdir].length, text);
  367. fcbptr = (fcb *)text;
  368. for(i = 0; i < rbn / sizeof(fcb); i++)
  369. {
  370. if(fcbptr->free)
  371. {
  372. if(fcbptr->attribute & 0x20)
  373. printf("%s\\\t\t<DIR>\t\t%d/%d/%d\t%02d:%02d:%02d\n", fcbptr->filename, (fcbptr->date >> 9) + 1980, (fcbptr->date >> 5) & 0x000f, fcbptr->date & 0x001f, fcbptr->time >> 11, (fcbptr->time >> 5) & 0x003f, fcbptr->time & 0x001f * 2);
  374. else
  375. printf("%s.%s\t\t%dB\t\t%d/%d/%d\t%02d:%02d:%02d\t\n", fcbptr->filename, fcbptr->exname, (int)(fcbptr->length), (fcbptr->date >> 9) + 1980, (fcbptr->date >> 5) & 0x000f, fcbptr->date & 0x1f, fcbptr->time >> 11, (fcbptr->time >> 5) & 0x3f, fcbptr->time & 0x1f * 2);
  376. }
  377. fcbptr++;
  378. }
  379. }
  380. void my_create(char *filename)
  381. {
  382. fcb *fcbptr;
  383. fat *fat1, *fat2;
  384. char *fname, *exname, text[MAXTEXT];
  385. unsigned short blkno;
  386. int rbn, i;
  387. time_t now;
  388. struct tm *nowtime;
  389. fat1 = (fat *)(myvhard + BLOCKSIZE);
  390. fat2 = (fat *)(myvhard + BLOCKSIZE);
  391. fname = strtok(filename, ".");
  392. exname = strtok(NULL, ".");
  393. if(strcmp(fname, "") == 0)
  394. {
  395. printf("Error,creating file must have a right name.\n");
  396. return;
  397. }
  398. if(!exname)
  399. {
  400. printf("Error,creating file must have a extern name.\n");
  401. return;
  402. }
  403. openfilelist[curdir].count = 0;
  404. rbn = do_read(curdir, openfilelist[curdir].length, text);
  405. fcbptr = (fcb *)text;
  406. for(i = 0; i < rbn / sizeof(fcb); i++)
  407. {
  408. if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
  409. {
  410. printf("Error,the filename is already exist!\n");
  411. return;
  412. }
  413. fcbptr++;
  414. }
  415. fcbptr = (fcb *)text;
  416. for(i = 0; i < rbn / sizeof(fcb); i++)
  417. {
  418. if(fcbptr->free == 0)
  419. break;
  420. fcbptr++;
  421. }
  422. blkno = findblock();
  423. if(blkno == -1)
  424. return;
  425. (fat1 + blkno)->id = END;
  426. (fat2 + blkno)->id = END;
  427. now = time(NULL);
  428. nowtime = localtime(&now);
  429. strcpy(fcbptr->filename, fname);
  430. strcpy(fcbptr->exname, exname);
  431. fcbptr->attribute = 0x00;
  432. fcbptr->time = nowtime->tm_hour * 2048 + nowtime->tm_min * 32 + nowtime->tm_sec / 2;
  433. fcbptr->date = (nowtime->tm_year - 80) * 512 + (nowtime->tm_mon + 1) * 32 + nowtime->tm_mday;
  434. fcbptr->first = blkno;
  435. fcbptr->length = 0;
  436. fcbptr->free = 1;
  437. openfilelist[curdir].count = i * sizeof(fcb);
  438. do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
  439. fcbptr = (fcb *)text;
  440. fcbptr->length = openfilelist[curdir].length;
  441. openfilelist[curdir].count = 0;
  442. do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
  443. openfilelist[curdir].fcbstate = 1;
  444. }
  445. void my_rm(char *filename)
  446. {
  447. fcb *fcbptr;
  448. fat *fat1, *fat2, *fatptr1, *fatptr2;
  449. char *fname, *exname, text[MAXTEXT];
  450. unsigned short blkno;
  451. int rbn, i;
  452. fat1 = (fat *)(myvhard + BLOCKSIZE);
  453. fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
  454. fname = strtok(filename, ".");
  455. exname = strtok(NULL, ".");
  456. if(strcmp(fname, "") == 0)
  457. {
  458. printf("Error,removing file must have a right name.\n");
  459. return;
  460. }
  461. if(!exname)
  462. {
  463. printf("Error,removing file must have a extern name.\n");
  464. return;
  465. }
  466. openfilelist[curdir].count = 0;
  467. rbn = do_read(curdir, openfilelist[curdir].length, text);
  468. fcbptr = (fcb *)text;
  469. for(i = 0; i < rbn / sizeof(fcb); i++)
  470. {
  471. if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
  472. break;
  473. fcbptr++;
  474. }
  475. if(i == rbn / sizeof(fcb))
  476. {
  477. printf("Error,the file is not exist.\n");
  478. return;
  479. }
  480. openfilelist[curdir].count = 0;
  481. rbn = do_read(curdir, openfilelist[curdir].length, text);
  482. fcbptr = (fcb *)text;
  483. for(i = 0; i < rbn / sizeof(fcb); i++)
  484. {
  485. if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
  486. break;
  487. fcbptr++;
  488. }
  489. if(i == rbn / sizeof(fcb))
  490. {
  491. printf("Error,the file is not exist.\n");
  492. return;
  493. }
  494. blkno = fcbptr->first;
  495. while(blkno != END)
  496. {
  497. fatptr1 = fat1 + blkno;
  498. fatptr2 = fat2 + blkno;
  499. blkno = fatptr1->id;
  500. fatptr1->id = FREE;
  501. fatptr2->id = FREE;
  502. }
  503. strcpy(fcbptr->filename, "");
  504. fcbptr->free = 0;
  505. openfilelist[curdir].count = i * sizeof(fcb);
  506. do_write(curdir, (char *)fcbptr, sizeof(fcb), 2);
  507. openfilelist[curdir].fcbstate = 1;
  508. }
  509. int my_open(char *filename)
  510. {
  511. fcb *fcbptr;
  512. char *fname, exname[3], *str, text[MAXTEXT];
  513. int rbn, fd, i;
  514. fname = strtok(filename, ".");
  515. str = strtok(NULL, ".");
  516. if(str)
  517. strcpy(exname, str);
  518. else
  519. strcpy(exname, "");
  520. for(i = 0; i < MAXOPENFILE; i++)
  521. {
  522. if(strcmp(openfilelist[i].filename, fname) == 0 && strcmp(openfilelist[i].exname, exname) == 0 && i != curdir)
  523. {
  524. printf("Error,the file is already open.\n");
  525. return -1;
  526. }
  527. }
  528. openfilelist[curdir].count = 0;
  529. rbn = do_read(curdir, openfilelist[curdir].length, text);
  530. fcbptr = (fcb *)text;
  531. for(i = 0; i < rbn / sizeof(fcb); i++)
  532. {
  533. if(strcmp(fcbptr->filename, fname) == 0 && strcmp(fcbptr->exname, exname) == 0)
  534. break;
  535. fcbptr++;
  536. }
  537. if(i == rbn / sizeof(fcb))
  538. {
  539. printf("Error,the file is not exist.\n");
  540. return -1;
  541. }
  542. fd = findopenfile();
  543. if(fd == -1)
  544. return -1;
  545. strcpy(openfilelist[fd].filename, fcbptr->filename);
  546. strcpy(openfilelist[fd].exname, fcbptr->exname);
  547. openfilelist[fd].attribute = fcbptr->attribute;
  548. openfilelist[fd].time = fcbptr->time;
  549. openfilelist[fd].date = fcbptr->date;
  550. openfilelist[fd].first = fcbptr->first;
  551. openfilelist[fd].length = fcbptr->length;
  552. openfilelist[fd].free = fcbptr->free;
  553. openfilelist[fd].dirno = openfilelist[curdir].first;
  554. openfilelist[fd].diroff = i;
  555. strcpy(openfilelist[fd].dir, openfilelist[curdir].dir);
  556. strcat(openfilelist[fd].dir, filename);
  557. if(fcbptr->attribute & 0x20)
  558. strcat(openfilelist[fd].dir, "\\");
  559. openfilelist[fd].father = curdir;
  560. openfilelist[fd].count = 0;
  561. openfilelist[fd].fcbstate = 0;
  562. openfilelist[fd].topenfile = 1;
  563. return fd;
  564. }
  565. int my_close(int fd)
  566. {
  567. fcb *fcbptr;
  568. int father;
  569. if(fd < 0 || fd >= MAXOPENFILE)
  570. {
  571. printf("Error,the file is not exist.\n");
  572. return -1;
  573. }
  574. if(openfilelist[fd].fcbstate)
  575. {
  576. fcbptr = (fcb *)malloc(sizeof(fcb));
  577. strcpy(fcbptr->filename, openfilelist[fd].filename);
  578. strcpy(fcbptr->exname, openfilelist[fd].exname);
  579. fcbptr->attribute = openfilelist[fd].attribute;
  580. fcbptr->time = openfilelist[fd].time;
  581. fcbptr->date = openfilelist[fd].date;
  582. fcbptr->first = openfilelist[fd].first;
  583. fcbptr->length = openfilelist[fd].length;
  584. fcbptr->free = openfilelist[fd].free;
  585. father = openfilelist[fd].father;
  586. openfilelist[father].count = openfilelist[fd].diroff * sizeof(fcb);
  587. do_write(father, (char *)fcbptr, sizeof(fcb), 2);
  588. free(fcbptr);
  589. openfilelist[fd].fcbstate = 0;
  590. }
  591. strcpy(openfilelist[fd].filename, "");
  592. strcpy(openfilelist[fd].exname, "");
  593. openfilelist[fd].topenfile = 0;
  594. return father;
  595. }
  596. int my_write(int fd)
  597. {
  598. fat *fat1, *fat2, *fatptr1, *fatptr2;
  599. int wstyle, len, ll, tmp;
  600. char text[MAXTEXT];
  601. unsigned short blkno;
  602. fat1 = (fat *)(myvhard + BLOCKSIZE);
  603. fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
  604. if(fd < 0 || fd >= MAXOPENFILE)
  605. {
  606. printf("The file is not exist!\n");
  607. return -1;
  608. }
  609. while(1)
  610. {
  611. printf("Please enter the number of write style:\n1.cut write\t2.cover write\t3.add write\n");
  612. scanf("%d", &wstyle);
  613. if(wstyle > 0 && wstyle < 4)
  614. break;
  615. printf("Input Error!");
  616. }
  617. getchar();
  618. switch(wstyle)
  619. {
  620. case 1:
  621. blkno = openfilelist[fd].first;
  622. fatptr1 = fat1 + blkno;
  623. fatptr2 = fat2 + blkno;
  624. blkno = fatptr1->id;
  625. fatptr1->id = END;
  626. fatptr2->id = END;
  627. while(blkno != END)
  628. {
  629. fatptr1 = fat1 + blkno;
  630. fatptr2 = fat2 + blkno;
  631. blkno = fatptr1->id;
  632. fatptr1->id = FREE;
  633. fatptr2->id = FREE;
  634. }
  635. openfilelist[fd].count = 0;
  636. openfilelist[fd].length = 0;
  637. break;
  638. case 2:
  639. openfilelist[fd].count = 0;
  640. break;
  641. case 3:
  642. openfilelist[fd].count = openfilelist[fd].length;
  643. break;
  644. default:
  645. break;
  646. }
  647. ll = 0;
  648. printf("please input write data(end with Ctrl+Z):\n");
  649. while(gets(text))
  650. {
  651. len = strlen(text);
  652. text[len++] = '\n';
  653. text[len] = '\0';
  654. tmp = do_write(fd, text, len, wstyle);
  655. if(tmp != -1)
  656. ll += tmp;
  657. if(tmp < len)
  658. {
  659. printf("Wirte Error!");
  660. break;
  661. }
  662. }
  663. return ll;
  664. }
  665. int do_write(int fd, char *text, int len, char wstyle)
  666. {
  667. fat *fat1, *fat2, *fatptr1, *fatptr2;
  668. unsigned char *buf, *blkptr;
  669. unsigned short blkno, blkoff;
  670. int i, ll;
  671. fat1 = (fat *)(myvhard + BLOCKSIZE);
  672. fat2 = (fat *)(myvhard + 3 * BLOCKSIZE);
  673. buf = (unsigned char *)malloc(BLOCKSIZE);
  674. if(buf == NULL)
  675. {
  676. printf("malloc failed!\n");
  677. return -1;
  678. }
  679. blkno = openfilelist[fd].first;
  680. blkoff = openfilelist[fd].count;
  681. fatptr1 = fat1 + blkno;
  682. fatptr2 = fat2 + blkno;
  683. while(blkoff >= BLOCKSIZE)
  684. {
  685. blkno = fatptr1->id;
  686. if(blkno == END)
  687. {
  688. blkno = findblock();
  689. if(blkno == -1)
  690. {
  691. free(buf);
  692. return -1;
  693. }
  694. fatptr1->id = blkno;
  695. fatptr2->id = blkno;
  696. fatptr1 = fat1 + blkno;
  697. fatptr2 = fat2 + blkno;
  698. fatptr1->id = END;
  699. fatptr2->id = END;
  700. }
  701. else
  702. {
  703. fatptr1 = fat1 + blkno;
  704. fatptr2 = fat2 + blkno;
  705. }
  706. blkoff = blkoff - BLOCKSIZE;
  707. }
  708. ll = 0;
  709. while(ll < len)
  710. {
  711. blkptr = (unsigned char *)(myvhard + blkno * BLOCKSIZE);
  712. for(i = 0; i < BLOCKSIZE; i++)
  713. buf[i] = blkptr[i];
  714. for(;blkoff < BLOCKSIZE; blkoff++)
  715. {
  716. buf[blkoff] = text[ll++];
  717. openfilelist[fd].count++;
  718. if(ll == len)
  719. break;
  720. }
  721. for(i = 0; i < BLOCKSIZE; i++)
  722. blkptr[i] = buf[i];
  723. if(ll < len)
  724. {
  725. blkno = fatptr1->id;
  726. if(blkno == END)
  727. {
  728. blkno = findblock();
  729. if(blkno == -1)
  730. break;
  731. fatptr1->id = blkno;
  732. fatptr2->id = blkno;
  733. fatptr1 = fat1 + blkno;
  734. fatptr2 = fat2 + blkno;
  735. fatptr1->id = END;
  736. fatptr2->id = END;
  737. }
  738. else
  739. {
  740. fatptr1 = fat1 + blkno;
  741. fatptr2 = fat2 + blkno;
  742. }
  743. blkoff = 0;
  744. }
  745. }
  746. if(openfilelist[fd].count > openfilelist[fd].length)
  747. openfilelist[fd].length = openfilelist[fd].count;
  748. openfilelist[fd].fcbstate = 1;
  749. free(buf);
  750. return ll;
  751. }
  752. int my_read(int fd, int len)
  753. {
  754. char text[MAXTEXT];
  755. int ll;
  756. if(fd < 0 || fd >= MAXOPENFILE)
  757. {
  758. printf("The File is not exist!\n");
  759. return -1;
  760. }
  761. openfilelist[fd].count = 0;
  762. ll = do_read(fd, len, text);
  763. if(ll != -1)
  764. printf("%s", text);
  765. else
  766. printf("Read Error!\n");
  767. return ll;
  768. }
  769. int do_read(int fd, int len, char *text)
  770. {
  771. fat *fat1, *fatptr;
  772. unsigned char *buf, *blkptr;
  773. unsigned short blkno, blkoff;
  774. int i, ll;
  775. fat1 = (fat *)(myvhard + BLOCKSIZE);
  776. buf = (unsigned char *)malloc(BLOCKSIZE);
  777. if(buf == NULL)
  778. {
  779. printf("malloc failed!\n");
  780. return -1;
  781. }
  782. blkno = openfilelist[fd].first;
  783. blkoff = openfilelist[fd].count;
  784. if(blkoff >= openfilelist[fd].length)
  785. {
  786. puts("Read out of range!");
  787. free(buf);
  788. return -1;
  789. }
  790. fatptr = fat1 + blkno;
  791. while(blkoff >= BLOCKSIZE)
  792. {
  793. blkno = fatptr->id;
  794. blkoff = blkoff - BLOCKSIZE;
  795. fatptr = fat1 + blkno;
  796. }
  797. ll = 0;
  798. while(ll < len)
  799. {
  800. blkptr = (unsigned char *)(myvhard + blkno * BLOCKSIZE);
  801. for(i = 0; i < BLOCKSIZE; i++)
  802. buf[i] = blkptr[i];
  803. for(; blkoff < BLOCKSIZE; blkoff++)
  804. {
  805. text[ll++] = buf[blkoff];
  806. openfilelist[fd].count++;
  807. if(ll == len || openfilelist[fd].count == openfilelist[fd].length)
  808. break;
  809. }
  810. if(ll < len && openfilelist[fd].count != openfilelist[fd].length)
  811. {
  812. blkno = fatptr->id;
  813. if(blkno == END)
  814. break;
  815. blkoff = 0;
  816. fatptr = fat1 + blkno;
  817. }
  818. }
  819. text[ll] = '\0';
  820. free(buf);
  821. return ll;
  822. }
  823. void my_exitsys()
  824. {
  825. FILE *fp;
  826. while(curdir)
  827. curdir = my_close(curdir);
  828. fp = fopen(myfilename, "w");
  829. fwrite(myvhard, SIZE, 1, fp);
  830. fclose(fp);
  831. free(myvhard);
  832. }
  833. unsigned short findblock()
  834. {
  835. unsigned short i;
  836. fat *fat1, *fatptr;
  837. fat1 = (fat *)(myvhard + BLOCKSIZE);
  838. for(i = 7; i < SIZE / BLOCKSIZE; i++)
  839. {
  840. fatptr = fat1 + i;
  841. if(fatptr->id == FREE)
  842. return i;
  843. }
  844. printf("Error,Can't find free block!\n");
  845. return -1;
  846. }
  847. int findopenfile()
  848. {
  849. int i;
  850. for(i = 0; i < MAXTEXT; i++)
  851. {
  852. if(openfilelist[i].topenfile == 0)
  853. return i;
  854. }
  855. printf("Error,open too many files!\n");
  856. return -1;
  857. }
  858. int main()
  859. {
  860. char cmd[15][10] = {"cd", "mkdir", "rmdir", "ls", "create", "rm", "open", "close", "write", "read", "exit"};
  861. char s[30], *sp;
  862. int cmdn, flag = 1, i;
  863. startsys();
  864. printf("*********************File System V1.0*******************************\n\n");
  865. printf("命令名\t\t命令参数\t\t命令说明\n\n");
  866. printf("cd\t\t目录名(路径名)\t\t切换当前目录到指定目录\n");
  867. printf("mkdir\t\t目录名\t\t\t在当前目录创建新目录\n");
  868. printf("rmdir\t\t目录名\t\t\t在当前目录删除指定目录\n");
  869. printf("ls\t\t无\t\t\t显示当前目录下的目录和文件\n");
  870. printf("create\t\t文件名\t\t\t在当前目录下创建指定文件\n");
  871. printf("rm\t\t文件名\t\t\t在当前目录下删除指定文件\n");
  872. printf("open\t\t文件名\t\t\t在当前目录下打开指定文件\n");
  873. printf("write\t\t无\t\t\t在打开文件状态下,写该文件\n");
  874. printf("read\t\t无\t\t\t在打开文件状态下,读取该文件\n");
  875. printf("close\t\t无\t\t\t在打开文件状态下,读取该文件\n");
  876. printf("exit\t\t无\t\t\t退出系统\n\n");
  877. printf("*********************************************************************\n\n");
  878. while(flag)
  879. {
  880. printf("%s>", openfilelist[curdir].dir);
  881. gets(s);
  882. cmdn = -1;
  883. if(strcmp(s, ""))
  884. {
  885. sp=strtok(s, " ");
  886. for(i = 0; i < 15; i++)
  887. {
  888. if(strcmp(sp, cmd[i]) == 0)
  889. {
  890. cmdn = i;
  891. break;
  892. }
  893. }
  894. //          printf("%d\n", cmdn);
  895. switch(cmdn)
  896. {
  897. case 0:
  898. sp = strtok(NULL, " ");
  899. if(sp && (openfilelist[curdir].attribute & 0x20))
  900. my_cd(sp);
  901. else
  902. printf("Please input the right command.\n");
  903. break;
  904. case 1:
  905. sp = strtok(NULL, " ");
  906. if(sp && (openfilelist[curdir].attribute & 0x20))
  907. my_mkdir(sp);
  908. else
  909. printf("Please input the right command.\n");
  910. break;
  911. case 2:
  912. sp = strtok(NULL, " ");
  913. if(sp && (openfilelist[curdir].attribute & 0x20))
  914. my_rmdir(sp);
  915. else
  916. printf("Please input the right command.\n");
  917. break;
  918. case 3:
  919. if(openfilelist[curdir].attribute & 0x20)
  920. my_ls();
  921. else
  922. printf("Please input the right command.\n");
  923. break;
  924. case 4:
  925. sp = strtok(NULL, " ");
  926. if(sp && (openfilelist[curdir].attribute & 0x20))
  927. my_create(sp);
  928. else
  929. printf("Please input the right command.\n");
  930. break;
  931. case 5:
  932. sp = strtok(NULL, " ");
  933. if(sp && (openfilelist[curdir].attribute & 0x20))
  934. my_rm(sp);
  935. else
  936. printf("Please input the right command.\n");
  937. break;
  938. case 6:
  939. sp = strtok(NULL, " ");
  940. if(sp && (openfilelist[curdir].attribute & 0x20))
  941. {
  942. if(strchr(sp, '.'))//查找sp中'.'首次出现的位置
  943. curdir = my_open(sp);
  944. else
  945. printf("the openfile should have exname.\n");
  946. }
  947. else
  948. printf("Please input the right command.\n");
  949. break;
  950. case 7:
  951. if(!(openfilelist[curdir].attribute & 0x20))
  952. curdir = my_close(curdir);
  953. else
  954. printf("No files opened.\n");
  955. break;
  956. case 8:
  957. if(!(openfilelist[curdir].attribute & 0x20))
  958. my_write(curdir);
  959. else
  960. printf("No files opened.\n");
  961. break;
  962. case 9:
  963. if(!(openfilelist[curdir].attribute & 0x20))
  964. my_read(curdir, openfilelist[curdir].length);
  965. else
  966. printf("No files opened.\n");
  967. break;
  968. case 10:
  969. if(openfilelist[curdir].attribute & 0x20)
  970. {
  971. my_exitsys();
  972. flag = 0;
  973. }
  974. else
  975. printf("Please input the right command.\n");
  976. break;
  977. default:
  978. printf("Please input the right command.\n");
  979. break;
  980. }
  981. }
  982. }
  983. return 0;
  984. }

【操作系统】C语言编写的FAT16文件系统的更多相关文章

  1. 运用Python语言编写获取Linux基本系统信息(二):文件系统使用情况获取

    本文跟着上一篇文章继续写,上一篇文章的链接 运用Python语言编写获取Linux基本系统信息(一):获得Linux版本.内核.当前时间 一.随便说说 获取文件系统使用情况的思路和上一篇获取主要系统是 ...

  2. FastDFS是使用c语言编写的开源高性能分布式文件系统

    FastDFS是什么 FastDFS是使用c语言编写的开源高性能分布式文件系统 是由淘宝开发平台部资深架构师余庆开发,FastDFS孵化平台板块 他对文件进行管理,功能包括文件存储,文件同步,文件访问 ...

  3. 如何用C语言编写病毒‘

    怎样用C语言编写病毒在分析病毒机理的基础上,用C语言写了一个小病毒作为实例,用TURBOC2.0实现.[Abstract] This paper introduce the charateristic ...

  4. FAT16文件系统简介

    有必要说明一下,以下对FAT16系统的介绍,很多都是参考文献.由于FAT16系统一般在U盘.MMC卡.SD卡以及一些小型存储设备上使用比较多,以后把这些小型存储设备统称为存储卡,这里仅局限于对存储卡的 ...

  5. 基于stm32f103zet6的FAT16文件系统学习1(初识FAT16)

    有了之前读写block的基础之后,准备弄个文件系统,之前没有接触过这东西,所以有很多都晕晕的,但是看到fat的源代码之后还是挺有信心的,因为之前一直过uboot,所以这个文件当然是小巫见大巫了.首先来 ...

  6. 电子工程师名片——FAT16文件系统

    从8月8号开始,连续一个月利用每天下班时间和周末的时间终于初步完成了一个电子工程师的电路板名片,就像U盘一样,不过这个FLASH只有64KB的大小,用的单片机是C8051F320,是一个USB型的单片 ...

  7. 运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程,把获取的信息存入数据库

    运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程 有关前两篇的链接: 运用Python语言编写获取Linux基本系统信息(一):获得Linux版本.内核.当前时间 运 ...

  8. 电子工程师名片——FAT16文件系统(转)

    源:电子工程师名片——FAT16文件系统 从8月8号开始,连续一个月利用每天下班时间和周末的时间终于初步完成了一个电子工程师的电路板名片,就像U盘一样,不过这个FLASH只有64KB的大小,用的单片机 ...

  9. C语言编译器为什么能够用C语言编写?

    不知道大家有没有想过一个问题:C语言编译器为什么能够用C语言编写? 所谓C语言编译器,就是把编程得到的文件,比如.c,.h的文件,进行读取,并对内容进行分析,按照C语言的规则,将其转换成cpu可以执行 ...

随机推荐

  1. amazon interview

    I'll be sitting for an Amazon interview in 3 months. Which website should I use to practice: SPOJ, H ...

  2. Python学习---IO的异步[tornado模块]

    tornado是一个异步非阻塞的WEB框架.它的异步非阻塞实际上就是用事件循环写的. 主要体现在2点: 1. 作为webserver可以接收请求,同时支持异步处理请求.Django只能处理完成上一个请 ...

  3. Linux 开机启动流程

    Linux的开机启动流程 1.开机BIOS自检                                             --> 检查CPU,硬盘等硬件信息 2.MBR[Major ...

  4. Skype for Business Server-呼叫质量仪表板(一)安装与配置

    第一篇:安装与配置 很多公司在运行过程中都遇到了难以追踪客服人员绩效的情况,公司没有有效的方法追踪员工在通过电话等远程方式解决客户问题.销售产品.客户关怀的情况.Skype for Business提 ...

  5. 最小生成数 克鲁斯卡尔 普里姆 matlab

    克鲁斯卡尔: function T=MST_Kruskal(G) n=0; if isfield(G,'w') && ~isempty(G.w) && size(G.w ...

  6. 鼠标有但是U盘读取不出来怎么办

    我今天就遇到了这个问题,搞了半天最后下了一个驱动人生,查看里面的回答才解决 就是把里面通用串行总控制器设置为隐藏文件可读之后选择把灰色的都删除就好了.具体可以在驱动人生里搜U盘不识别,之后就4,5步即 ...

  7. Jupyter Notebook的使用

    命令模式 (按键 Esc 开启) Enter : 转入编辑模式 Shift-Enter : 运行本单元,选中下个单元 Ctrl-Enter : 运行本单元 Alt-Enter : 运行本单元,在其下插 ...

  8. linux_bc命令

    bc 命令:     bc 命令是用于命令行计算器. 它类似基本的计算器. 使用这个计算器可以做基本的数学运算. 语法:  语法是      bc [命令开关]命令开关:      -c 仅通过编译. ...

  9. Java基础加强之并发(三)Thread中start()和run()的区别

    Thread中start()和run()的区别 start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法.start()不能被重复调用.run()   : run()就和普通的成 ...

  10. 【node.js】Stream(流)

    Stream 有四种流类型: Readable - 可读操作. Writable - 可写操作. Duplex - 可读可写操作. Transform - 操作被写入数据,然后读出结果. 所有的 St ...