【操作系统】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. jenkins 安卓打包生成二维码下载

    先来张图看看吧 构思 jenkins gradle 打包apk文件,python myqr 模块生成二维码 放入nginx 访问图片的路径,apk安装包放在 nginx 下载目录. 环境 centos ...

  2. September 19th 2017 Week 38th Tuesday

    Live boldly. Push yourself. Don't settle. 勇敢生活,突破自我,永不设限! Don't indulge in the past, whether it was ...

  3. November 7th 2016 Week 46th Monday

    A friend is one who knows you and loves you just the same. 朋友是懂你并爱你的人. Friendship means inclusion, l ...

  4. PostProcess崩溃

    1.__debugbreak 功能暂停程序执行,打开调试器,进入调试模式. 2.重要参考: https://blog.csdn.net/phenixyf/article/details/4930457 ...

  5. 原生 JS 的 Base64 转码

    JavaScript 原生提供两个 Base64 相关的方法: btoa():任意值转为 Base64 编码 atob():Base64 编码转为原来的值 注意:这两个方法不适合非 ASCII 码的字 ...

  6. 洛谷 P1073 最优贸易

    题目描述 CC C 国有 n n n 个大城市和 m mm 条道路,每条道路连接这 nnn 个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这 mmm 条道路中有一部分为单向通行的道路 ...

  7. 【转】彻底理解android中的内部存储与外部存储

    我们先来考虑这样一个问题: 打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的 ...

  8. 适合自己的adblock过滤列表

    轻微完美主义,极简主义 已屏蔽广告: 1.CSDN的广告 2.百度侧栏热点搜索 3. 知乎广告 4.stackoverflow的推送广告 5.LeetCode的推送的是否见过这个题 bbs.csdn. ...

  9. RabbitMQ如何保证发送端消息的可靠投递

    消息发布者向RabbitMQ进行消息投递时默认情况下是不返回发布者该条消息在broker中的状态的,也就是说发布者不知道这条消息是否真的抵达RabbitMQ的broker之上,也因此会发生消息丢失的情 ...

  10. VSC 插件开发从入门到Hello World

    1.原理放一边,我们先来个Hello,World 1.1 安装基础环境 需要的基础环境列表: Node.js npm vs code yo generator-code yo:全称Yeoman,可以把 ...