2022年操作系统实验文件管理C++代码 2.pdf
#include #include #include #include #include using namespace std; #define BLKSIZE 512 / 数据块的大小#define BLKNUM 512 / 数据块的块数#define INODESIZE 32 / i 节点的大小#define INODENUM 32 / i 节点的数目#define FILENUM 8 / 打开文件表的数目/ 用户typedef struct char user_name10; / 用户名char password10; / 密码 User; /i 节点typedef struct short inum; / 文件 i 节点号char file_name10; / 文件名char type; / 文件类型char user_name10; / 文件所有者short iparent; / 父目录的i 节点号short length; / 文件长度short address2; / 存放文件的地址 Inode; / 打开文件表typedef struct short inum; / i 节点号char file_name10; / 文件名short mode; / 读写模式 (1:read, 2:write, / 3:read and write) File_table; / 申明函数void login(void); void init(void); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 19 页 - - - - - - - - - int analyse(char *); void save_inode(int); int get_blknum(void); void read_blk(int); void write_blk(int); void release_blk(int); void pathset(); void del(int); / 用户命令处理函数void help(void); void cd(void); void dir(void); void mkdir(void); void creat(void); void open(void); void read(void); void write(void); void close(void); void delet(void); void logout(void); void command(void); void quit(); /main.cpp 文件/#include head.h / 定义全局变量char choice; int argc; / 用户命令的参数个数char *argv5; / 用户命令的参数int inum_cur; / 当前目录char temp2*BLKSIZE; / 缓冲区User user; / 当前的用户char bitmapBLKNUM; / 位图数组Inode inode_arrayINODENUM; / i 节点数组File_table file_arrayFILENUM; / 打开文件表数组char image_name10 = data.dat; / 文件系统名称FILE *fp; / 打开文件指针/ 创建映像hd,并将所有用户和文件清除void format(void) int i; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 19 页 - - - - - - - - - Inode inode; printf(Will be to format filesystem.n); printf(WARNING:ALL DATA ON THIS FILESYSTEM WILL BE LOST!n); printf(Proceed with Format(Y/N)?); scanf(%c, &choice); getchar(); if(choice = y) | (choice = Y) if(fp=fopen(image_name, w+b) = NULL) printf(Cant create file %sn, image_name); exit(-1); for(i = 0; i BLKSIZE; i+) fputc(0, fp); inode.inum = 0; strcpy(inode.file_name, /); inode.type = d; strcpy(inode.user_name, /); inode.iparent = 0; inode.length = 0; inode.address0 = -1; inode.address1 = -1; fwrite(&inode, sizeof(Inode), 1, fp); inode.inum = -1; for(i = 0; i 31; i+) fwrite(&inode, sizeof(Inode), 1, fp); for(i = 0; i BLKNUM*BLKSIZE; i+) fputc(0, fp); fclose(fp); / 打开文件user.txt if(fp=fopen(user.txt, w+) = NULL) printf(Cant create file %sn, user.txt); exit(-1); fclose(fp); printf(Filesystem created successful.Please first login!n); return ; / 功能 : 用户登陆,如果是新用户则创建用户void login(void) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 19 页 - - - - - - - - - char *p; int flag; char user_name10; char password10; char file_name10 = user.txt; do printf(login:); gets(user_name); printf(password:); p=password; while(*p=getch() if(*p = 0 x0d) *p=0; /将输入的回车键转换成空格break; printf(*); / 将输入的密码以* 号显示p+; flag = 0; if(fp = fopen(file_name, r+) = NULL) printf(nCant open file %s.n, file_name); printf(This filesystem not exist, it will be create!n); format(); login(); while(!feof(fp) fread(&user, sizeof(User), 1, fp); / 已经存在的用户, 且密码正确if(!strcmp(user.user_name, user_name) & !strcmp(user.password, password) fclose(fp); printf(n); return ; / 已经存在的用户, 但密码错误else if(!strcmp(user.user_name, user_name) printf(nThis user is exist, but password is incorrect.n); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 19 页 - - - - - - - - - flag = 1; fclose(fp); break; if(flag = 0) break; while(flag); / 创建新用户if(flag = 0) printf(nDo you want to creat a new user?(y/n):); scanf(%c, &choice); gets(temp); if(choice = y) | (choice = Y) strcpy(user.user_name, user_name); strcpy(user.password, password); fwrite(&user, sizeof(User), 1, fp); fclose(fp); return ; if(choice = n) | (choice = N) login(); / 功能 : 将所有 i 节点读入内存void init(void) int i; if(fp = fopen(image_name, r+b) = NULL) printf(Cant open file %s.n, image_name); exit(-1); / 读入位图for(i = 0; i BLKNUM; i+) bitmapi = fgetc(fp); / 显示位图/ 读入 i 节点信息for(i = 0; i INODENUM; i+) fread(&inode_arrayi, sizeof(Inode), 1, fp); / 显示 i 节点/ 当前目录为根目录inum_cur = 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 19 页 - - - - - - - - - / 初始化打开文件表for(i = 0; i FILENUM; i+) file_arrayi.inum = -1; / 功能 : 分析用户命令, 将分析结果填充argc 和 argv / 结果 : 0-13 为系统命令 , 14 为命令错误int analyse(char *str) int i; char temp20; char *ptr_char; char *syscmd=help, cd, dir, mkdir, create, open, read, write, close, delet, logout, clear,format,quit; argc = 0; for(i = 0, ptr_char = str; *ptr_char != 0; ptr_char+) if(*ptr_char != ) while(*ptr_char != & (*ptr_char != 0) tempi+ = *ptr_char+; argvargc = (char *)malloc(i+1); strncpy(argvargc, temp, i); argvargci = 0; argc+; i = 0; if(*ptr_char = 0) break; if(argc != 0) for(i = 0; (i 14) & strcmp(argv0, syscmdi); i+); return i; else return 14; / 功能 : 将 num 号 i 节点保存到hd.dat void save_inode(int num) if(fp=fopen(image_name, r+b) = NULL) printf(Cant open file %sn, image_name); exit(-1); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 19 页 - - - - - - - - - fseek(fp, BLKNUM +num*sizeof(Inode), SEEK_SET); fwrite(&inode_arraynum, sizeof(Inode), 1, fp); fclose(fp); / 功能 : 申请一个数据块int get_blknum(void) int i; for(i = 0; i 512) add1 = inode_arraynum.address1; if(fp = fopen(image_name, r+b) = NULL) printf(Cant open file %s.n, image_name); exit(-1); fseek(fp, BLKSIZE+INODESIZE*INODENUM +add0*BLKSIZE, SEEK_SET); ch = fgetc(fp); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 19 页 - - - - - - - - - for(i=0; (i len) & (ch != 0) & (i = 512) fseek(fp,BLKSIZE+INODESIZE*INODENUM+add1*BLKSIZE, SEEK_SET); ch = fgetc(fp); for(; (i len) & (ch != 0); i+) tempi = ch; ch = fgetc(fp); tempi = 0; fclose(fp); / 功能 : 将 temp 的内容输入hd 的数据区void write_blk(int num) int i, len; int add0, add1; add0 = inode_arraynum.address0; len = inode_arraynum.length; if(fp = fopen(image_name, r+b) = NULL) printf(Cant open file %s.n, image_name); exit(-1); fseek(fp, BLKSIZE+INODESIZE*INODENUM+add0*BLKSIZE, SEEK_SET); for(i=0; (ilen)&(tempi!=0)&(i 512); i+) fputc(tempi, fp); if(i = 512) add1 = inode_arraynum.address1; fseek(fp, BLKSIZE+INODESIZE*INODENUM+add1*BLKSIZE, SEEK_SET); for(; (i len) & (tempi != 0); i+) fputc(tempi, fp); fputc(0, fp); fclose(fp); / 功能 : 释放文件块号为num 的文件占用的空间名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 19 页 - - - - - - - - - void release_blk(int num) FILE *fp; if(fp=fopen(image_name, r+b) = NULL) printf(Cant open file %sn, image_name); exit(-1); bitmapnum = 0; fseek(fp, num, SEEK_SET); fputc(0, fp); fclose(fp); / 功能 : 显示帮助命令void help(void) printf(command: n help - show help menu n clear - clear the screen n cd - change directory n mkdir - make directory n create - create a new file n open - open a exist file n read - read a file n write - write something to a file n close - close a file n delet - delete a exist file or directory n format - format a exist filesystem n logout - exit user n quit - exit this systemn); / 设置文件路径void pathset() char path50; int m,n; if(inode_arrayinum_cur.inum = 0) strcpy(path,user.user_name); else strcpy(path,user.user_name); m=0; n=inum_cur; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 19 页 - - - - - - - - - while(m != inum_cur) while(inode_arrayn.iparent != m) n = inode_arrayn.iparent; strcat(path,/); strcat(path,inode_arrayn.file_name); m = n; n = inum_cur; printf(%s$,path); / 功能 : 切换目录 (cd . 或者cd dir1) void cd(void) int i; if(argc != 2) printf(Command cd must have two args. n); return ; if(!strcmp(argv1, .) inum_cur = inode_arrayinum_cur.iparent; else for(i = 0; i 0)& (inode_arrayi.type=d)& (inode_arrayi.iparent=inum_cur)& !strcmp(inode_arrayi.file_name,argv1)& !strcmp(inode_arrayi.user_name,user.user_name) break; if(i = INODENUM) printf(This directory isnt exsited.n); else inum_cur = i; / 功能 : 显示当前目录下的子目录和文件(dir) void dir(void) int i; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 19 页 - - - - - - - - - int dcount=0,fcount=0; short bcount=0; if(argc != 1) printf(Command dir must have one args. n); return ; / 遍历 i 节点数组 , 显示当前目录下的子目录和文件名for(i = 0; i 0) & (inode_arrayi.iparent = inum_cur)& !strcmp(inode_arrayi.user_name,user.user_name) if(inode_arrayi.type = d) dcount+; printf(%-20sn, inode_arrayi.file_name); else fcount+; bcount+=inode_arrayi.length; printf(%-20s%12d bytesn, inode_arrayi.file_name,inode_arrayi.length); printf(n %d file(s)%11d bytesn,fcount,bcount); printf( %d dir(s) %11d bytes FreeSpacen,dcount,1024*1024-bcount); / 功能 : 在当前目录下创建子目录(mkdir dir1) void mkdir(void) int i; if(argc != 2) printf(command mkdir must have two args. n); return ; / 遍历 i 节点数组 , 查找未用的i 节点for(i = 0; i INODENUM; i+) if(inode_arrayi.inum 0) break; if(i = INODENUM) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 19 页 - - - - - - - - - printf(Inode is full.n); exit(-1); inode_arrayi.inum = i; strcpy(inode_arrayi.file_name, argv1); inode_arrayi.type = d; strcpy(inode_arrayi.user_name,user.user_name); inode_arrayi.iparent = inum_cur; inode_arrayi.length = 0; save_inode(i); / 功能 : 在当前目录下创建文件(creat file) void create(void) int i; if(argc != 2) printf(command creat must have two args. n); return ; for(i = 0; i 0) & (inode_arrayi.type = f) & !strcmp(inode_arrayi.file_name, argv1) printf(This file is exsit.n); return ; for(i = 0; i INODENUM; i+) if(inode_arrayi.inum 0) break; if(i = INODENUM) printf(Inode is full.n); exit(-1); inode_arrayi.inum = i; strcpy(inode_arrayi.file_name, argv1); inode_arrayi.type = f; strcpy(inode_arrayi.user_name, user.user_name); inode_arrayi.iparent = inum_cur; inode_arrayi.length = 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 19 页 - - - - - - - - - save_inode(i); / 功能 : 打开当前目录下的文件(open file1) void open() int i, inum, mode, filenum; if(argc != 2) printf(command open must have two args. n); return ; for(i = 0; i 0) & (inode_arrayi.type = f) & !strcmp(inode_arrayi.file_name,argv1)& !strcmp(inode_arrayi.user_name,user.user_name) break; if(i = INODENUM) printf(The file you want to open doesnt exsited.n); return ; inum = i; printf(Please input open mode:(1: read, 2: write, 3: read and write):); scanf(%d, &mode); getchar(); if(mode 3) printf(Open mode is wrong.n); return; for(i = 0; i FILENUM; i+) if(file_arrayi.inum 0) break; if(i = FILENUM) printf(The file table is full, please close some file.n); return ; filenum = i; file_arrayfilenum.inum = inum; strcpy(file_arrayfilenum.file_name, inode_arrayinum.file_name); file_arrayfilenum.mode = mode; printf(Open file %s by , file_arrayfilenum.file_name); if(mode = 1) printf(read only.n); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 19 页 - - - - - - - - - else if(mode = 2) printf(write only.n); else printf(read and write.n); / 功能 : 从文件中读出字符(read file1) void read() int i, inum; if(argc != 2) printf(command read must have two args. n); return; for(i = 0; i 0) & !strcmp(file_arrayi.file_name,argv1) break; if(i = FILENUM) printf(Open %s first.n, argv1); return ; else if(file_arrayi.mode = 2) printf(Cant read %s.n, argv1); return ; inum = file_arrayi.inum; printf(The length of %s:%d.n, argv1, inode_arrayinum.length); if(inode_arrayinum.length 0) read_blk(inum); for(i = 0; (i inode_arrayinum.length) & (tempi != 0); i+) printf(%c, tempi); / 功能 : 向文件中写入字符(write file1) void write() int i, inum, length; if(argc != 2) printf(Command write must have two args. n); return ; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 19 页 - - - - - - - - - for(i = 0; i 0)& !strcmp(file_arrayi.file_name,argv1) break; if(i = FILENUM) printf(Open %s first.n, argv1); return ; else if(file_arrayi.mode = 1) printf(Cant write %s.n, argv1); return ; inum = file_arrayi.inum; printf(The length of %s:%dn, inode_arrayinum.file_name, inode_arrayinum.length); if(inode_arrayinum.length = 0) i=0; inode_arrayinum.address0 = get_blknum(); printf(Input the data(CTRL+Z to end):n); while(i 512) inode_arrayinum.address1 = get_blknum(); save_inode(inum); write_blk(inum); else printf(This file cant be written.n); / 功能 : 关闭已经打开的文件(close file1) void close(void) int i; if(argc != 2) printf(Command close must have two args. n); return ; for(i = 0; i 0) & 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 19 页 - - - - - - - - - !strcmp(file_arrayi.file_name, argv1) break; if(i = FILENUM) printf(This file doesnt be opened.n); return ; else file_arrayi.inum = -1; printf(Close %s success!n, argv1); / 回收 i 节点,有文件则删除文件void del(int i) inode_arrayi.inum = -1; if(inode_arrayi.length 0) release_blk(inode_arrayi.address0); if(inode_arrayi.length = 512) release_blk(inode_arrayi.address1); save_inode(i); / 删除子目录树和文件void delet(void) if(argc != 2) printf(Command delete must have two args. n); return ; int n,t,i; stack istk; for(i = 0; i =0) & (inode_arrayi.iparent = inum_cur)& (!strcmp(inode_arrayi.file_name,argv1)& (!strcmp(inode_arrayi.user_name,user.user_name) n=inode_arrayi.inum; break; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 19 页 - - - - - - - - - if(i=INODENUM) puts(Directory ERROR); else istk.push(n); while(!istk.empty() t=istk.top(); istk.pop(); del(t); for(i = 0; i =0) &(inode_arrayi.iparent = t) istk.push(i); / 功能 : 退出当前用户(logout) void logout() printf(Do you want to exit this user(y/n)?); scanf(%c, &choice); getchar(); if(choice = y) | (choice = Y) printf(nCurrent user has exited!n); login(); return ; / 功能 : 退出文件系统(quit) void quit() printf(Do you want to exist(y/n):); scanf(%c, &choice); getchar(); if(choice = y) | (choice = Y) exit(0); / 功能 : 显示错误void errcmd() printf(Command Error!n); / 清空内存中存在的用户名名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 19 页 - - - - - - - - - void free_user() int i; for(i=0;i10;i+) user.user_namei=0; / 功能 : 循环执行用户输入的命令, 直到 logout / help, cd, dir, mkdir, creat, open,read, write, close, delete, logout, clear, format,quit void command(void) char cmd100; system(cls); do pathset(); gets(cmd); switch(analyse(cmd) case 0: help(); break; case 1: cd(); break; case 2: dir(); break; case 3: mkdir(); break; case 4: create(); break; case 5: open(); break; case 6: read(); break; case 7: write(); break; case 8: close(); break; case 9: delet(); break; case 10: logout();break; case 11: system(cls);break; case 12: 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页,共 19 页 - - - - - - - - - format(); init(); free_user(); login();break; case 13: quit(); break; case 14: errcmd(); break; default: break; while(1); / 主函数int main(void) login(); init(); command(); return 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 19 页,共 19 页 - - - - - - - - -