操作系统试验—快速文件系统源代码
- 格式:doc
- 大小:43.50 KB
- 文档页数:8
#include <stdio.h>#include <stdlib.h>#include <conio.h>#include <string.h>#include<stack>using namespace std;#define BLKSIZE 512// 数据块的大小#define BLKNUM 512// 数据块的块数#define INODESIZE 32// i节点的大小#define INODENUM 32// i节点的数目#define FILENUM 8// 打开文件表的数目//用户typedef struct{char user_name[10];// 用户名char password[10];// 密码} User;//i节点typedef struct{short inum; // 文件i节点号char file_name[10]; // 文件名char type; // 文件类型char user_name[10]; // 文件所有者short iparent; // 父目录的i节点号short length; // 文件长度short address[2]; // 存放文件的地址} Inode;//打开文件表typedef struct{short inum;// i节点号char file_name[10]; // 文件名short mode;// 读写模式(1:read, 2:write,// 3:read and write) } File_table;// 申明函数void login(void);void init(void);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*argv[5];// 用户命令的参数int inum_cur;// 当前目录char temp[2*BLKSIZE];// 缓冲区User user;// 当前的用户char bitmap[BLKNUM];// 位图数组Inode inode_array[INODENUM];// i节点数组File_table file_array[FILENUM];// 打开文件表数组char image_name[10] = "data.dat";// 文件系统名称FILE*fp;// 打开文件指针//创建映像hd,并将所有用户和文件清除void format(void){int i;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("Can't create file %s\n", image_name);exit(-1);}for(i = 0; i < BLKSIZE; i++)fputc('0', fp);inode.inum = 0;strcpy(inode.file_name, "/");inode.type = 'd';strcpy(er_name, "/");inode.iparent = 0;inode.length = 0;inode.address[0] = -1;inode.address[1] = -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.txtif((fp=fopen("user.txt", "w+")) == NULL){printf("Can't create file %s\n", "user.txt");exit(-1);}fclose(fp);printf("Filesystem created successful.Please first login!\n");}return ;}// 功能: 用户登陆,如果是新用户则创建用户void login(void){char *p;int flag;char user_name[10];char password[10];char file_name[10] = "user.txt";do{printf("login:");gets(user_name);printf("password:");p=password;while(*p=getch()){if(*p == 0x0d){*p='\0'; //将输入的回车键转换成空格break;}printf("*"); //将输入的密码以"*"号显示p++;}flag = 0;if((fp = fopen(file_name, "r+")) == NULL){printf("\nCan't 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(er_name, user_name) &&!strcmp(user.password, password)){fclose(fp);printf("\n");return ;}// 已经存在的用户, 但密码错误else if(!strcmp(er_name, user_name)){printf("\nThis user is exist, but password is incorrect.\n");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(er_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("Can't open file %s.\n", image_name);exit(-1);}// 读入位图for(i = 0; i < BLKNUM; i++)bitmap[i] = fgetc(fp);// 显示位图// 读入i节点信息for(i = 0; i < INODENUM; i++)fread(&inode_array[i], sizeof(Inode), 1, fp);// 显示i节点// 当前目录为根目录inum_cur = 0;// 初始化打开文件表for(i = 0; i < FILENUM; i++)file_array[i].inum = -1;}// 功能: 分析用户命令, 将分析结果填充argc和argv// 结果: 0-13为系统命令, 14为命令错误int analyse(char *str){int i;char temp[20];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'))temp[i++] = *ptr_char++;argv[argc] = (char *)malloc(i+1);strncpy(argv[argc], temp, i);argv[argc][i] = '\0';argc++;i = 0;if(*ptr_char == '\0') break;}}if(argc != 0){for(i = 0; (i < 14) && strcmp(argv[0], syscmd[i]); i++);return i;}elsereturn 14;}// 功能: 将num号i节点保存到hd.datvoid save_inode(int num){if((fp=fopen(image_name, "r+b")) == NULL){printf("Can't open file %s\n", image_name);exit(-1);}fseek(fp, BLKNUM +num*sizeof(Inode), SEEK_SET);fwrite(&inode_array[num], sizeof(Inode), 1, fp);fclose(fp);}// 功能: 申请一个数据块int get_blknum(void){int i;for(i = 0; i < BLKNUM; i++)if(bitmap[i] == '0') break;// 未找到空闲数据块if(i == BLKNUM){printf("Data area is full.\n");exit(-1);}bitmap[i] = '1';if((fp=fopen(image_name, "r+b")) == NULL){printf("Can't open file %s\n", image_name);exit(-1);}fseek(fp, i, SEEK_SET);fputc('1', fp);fclose(fp);return i;}// 功能: 将i节点号为num的文件读入tempvoid read_blk(int num){int i, len;char ch;int add0, add1;len = inode_array[num].length;add0 = inode_array[num].address[0];if(len > 512)add1 = inode_array[num].address[1];if((fp = fopen(image_name, "r+b")) == NULL){printf("Can't open file %s.\n", image_name);exit(-1);}fseek(fp, BLKSIZE+INODESIZE*INODENUM +add0*BLKSIZE, SEEK_SET);ch = fgetc(fp);for(i=0; (i < len) && (ch != '\0') && (i < 512); i++){temp[i] = ch;ch = fgetc(fp);}if(i >= 512){fseek(fp,BLKSIZE+INODESIZE*INODENUM+add1*BLKSIZE, SEEK_SET);ch = fgetc(fp);for(; (i < len) && (ch != '\0'); i++){temp[i] = ch;ch = fgetc(fp);}}temp[i] = '\0';fclose(fp);}// 功能: 将temp的内容输入hd的数据区void write_blk(int num){int i, len;int add0, add1;add0 = inode_array[num].address[0];len = inode_array[num].length;if((fp = fopen(image_name, "r+b")) == NULL){printf("Can't open file %s.\n", image_name);exit(-1);}fseek(fp, BLKSIZE+INODESIZE*INODENUM+add0*BLKSIZE, SEEK_SET);for(i=0; (i<len)&&(temp[i]!='\0')&&(i < 512); i++)fputc(temp[i], fp);if(i == 512){add1 = inode_array[num].address[1];fseek(fp, BLKSIZE+INODESIZE*INODENUM+add1*BLKSIZE, SEEK_SET);for(; (i < len) && (temp[i] != '\0'); i++)fputc(temp[i], fp);}fputc('\0', fp);fclose(fp);}// 功能: 释放文件块号为num的文件占用的空间void release_blk(int num){FILE *fp;if((fp=fopen(image_name, "r+b")) == NULL){printf("Can't open file %s\n", image_name);exit(-1);}bitmap[num] = '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 system\n");}//设置文件路径void pathset(){char path[50];int m,n;if(inode_array[inum_cur].inum == 0)strcpy(path,er_name);else{strcpy(path,er_name);m=0;n=inum_cur;while(m != inum_cur){while(inode_array[n].iparent != m){n = inode_array[n].iparent;}strcat(path,"/");strcat(path,inode_array[n].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(argv[1], ".."))inum_cur = inode_array[inum_cur].iparent;else{for(i = 0; i < INODENUM; i++)if((inode_array[i].inum>0)&&(inode_array[i].type=='d')&&(inode_array[i].iparent==inum_cur)&&!strcmp(inode_array[i].file_name,argv[1])&&!strcmp(inode_array[i].user_name,er_name))break;if(i == INODENUM)printf("This directory isn't exsited.\n");elseinum_cur = i;}}// 功能: 显示当前目录下的子目录和文件(dir)void dir(void){int i;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 < INODENUM; i++)if((inode_array[i].inum> 0) &&(inode_array[i].iparent == inum_cur)&&!strcmp(inode_array[i].user_name,er_name)){if(inode_array[i].type == 'd'){dcount++;printf("%-20s<DIR>\n", inode_array[i].file_name);}else{fcount++;bcount+=inode_array[i].length;printf("%-20s%12d bytes\n", inode_array[i].file_name,inode_array[i].length);}}printf("\n %d file(s)%11d bytes\n",fcount,bcount);printf(" %d dir(s) %11d bytes FreeSpace\n",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_array[i].inum < 0) break;if(i == INODENUM){printf("Inode is full.\n");exit(-1);}inode_array[i].inum = i;strcpy(inode_array[i].file_name, argv[1]);inode_array[i].type = 'd';strcpy(inode_array[i].user_name,er_name);inode_array[i].iparent = inum_cur;inode_array[i].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 < INODENUM; i++){if((inode_array[i].inum > 0) &&(inode_array[i].type == 'f') &&!strcmp(inode_array[i].file_name, argv[1])) {printf("This file is exsit.\n");return ;}}for(i = 0; i < INODENUM; i++)if(inode_array[i].inum < 0) break;if(i == INODENUM){printf("Inode is full.\n");exit(-1);}inode_array[i].inum = i;strcpy(inode_array[i].file_name, argv[1]);inode_array[i].type = 'f';strcpy(inode_array[i].user_name, er_name);inode_array[i].iparent = inum_cur;inode_array[i].length = 0;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 < INODENUM; i++)if((inode_array[i].inum > 0) &&(inode_array[i].type == 'f') &&!strcmp(inode_array[i].file_name,argv[1])&&!strcmp(inode_array[i].user_name,er_name))break;if(i == INODENUM){printf("The file you want to open doesn't exsited.\n");return ;}inum = i;printf("Please input open mode:(1: read, 2: write, 3: read and write):");scanf("%d", &mode);getchar();if((mode < 1) || (mode > 3)){printf("Open mode is wrong.\n");return;}for(i = 0; i < FILENUM; i++)if(file_array[i].inum < 0) break;if(i == FILENUM){printf("The file table is full, please close some file.\n");return ;}filenum = i;file_array[filenum].inum = inum;strcpy(file_array[filenum].file_name, inode_array[inum].file_name);file_array[filenum].mode = mode;printf("Open file %s by ", file_array[filenum].file_name);if(mode == 1) printf("read only.\n");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 < FILENUM; i++)if((file_array[i].inum > 0) &&!strcmp(file_array[i].file_name,argv[1]))break;if(i == FILENUM){printf("Open %s first.\n", argv[1]);return ;}else if(file_array[i].mode == 2){printf("Can't read %s.\n", argv[1]);return ;}inum = file_array[i].inum;printf("The length of %s:%d.\n", argv[1], inode_array[inum].length);if(inode_array[inum].length > 0){read_blk(inum);for(i = 0; (i < inode_array[inum].length) && (temp[i] != '\0'); i++) printf("%c", temp[i]);}}// 功能: 向文件中写入字符(write file1)void write(){int i, inum, length;if(argc != 2){printf("Command write must have two args. \n");return ;}for(i = 0; i < FILENUM; i++)if((file_array[i].inum>0)&&!strcmp(file_array[i].file_name,argv[1])) break;if(i == FILENUM){printf("Open %s first.\n", argv[1]);return ;}else if(file_array[i].mode == 1){printf("Can't write %s.\n", argv[1]);return ;}inum = file_array[i].inum;printf("The length of %s:%d\n", inode_array[inum].file_name, inode_array[inum].length);if(inode_array[inum].length == 0){i=0;inode_array[inum].address[0] = get_blknum();printf("Input the data(CTRL+Z to end):\n");while(i<1023&&(temp[i]=getchar())!=EOF) i++;temp[i]='\0';length=strlen(temp)+1;inode_array[inum].length=length;if(length > 512)inode_array[inum].address[1] = get_blknum();save_inode(inum);write_blk(inum);}elseprintf("This file can't 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 < FILENUM; i++)if((file_array[i].inum > 0) &&!strcmp(file_array[i].file_name, argv[1])) break;if(i == FILENUM){printf("This file doesn't be opened.\n");return ;}else{file_array[i].inum = -1;printf("Close %s success!\n", argv[1]);}}//回收i节点,有文件则删除文件void del(int i){inode_array[i].inum = -1;if(inode_array[i].length > 0){release_blk(inode_array[i].address[0]);if(inode_array[i].length >= 512)release_blk(inode_array[i].address[1]);}save_inode(i);}//删除子目录树和文件void delet(void){if(argc != 2){printf("Command delete must have two args. \n");return ;}int n,t,i;stack<int> istk;for(i = 0; i < INODENUM; i++)//查找待删除子目录if((inode_array[i].inum >=0) &&(inode_array[i].iparent == inum_cur)&&(!strcmp(inode_array[i].file_name,argv[1]))&&(!strcmp(inode_array[i].user_name,er_name))) {n=inode_array[i].inum;break;}if(i==INODENUM) puts("Directory ERROR");else{istk.push(n);while(!istk.empty()){t=istk.top();istk.pop();del(t);for(i = 0; i < INODENUM; i++)if((inode_array[i].inum >=0) &&(inode_array[i].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");}//清空内存中存在的用户名void free_user(){int i;for(i=0;i<10;i++)er_name[i]='\0';}// 功能: 循环执行用户输入的命令, 直到logout// "help", "cd", "dir", "mkdir", "creat", "open","read", "write", "close", "delete", "logout", "clear", "format","quit"void command(void){char cmd[100];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: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;}。
文件管理系统模拟1.实验目的通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现 2.实验内容为Linux 系统设计一个简单的二级文件系统。
要求做到以下几点: (1)可以实现下列几条命令(至少4条) login 用户登录 dir列文件目录create 创建文件 delete 删除文件open 打开文件 close 关闭文件 read 读文件 write写文件(2)列目录时要列出文件名、物理地址、保护码和文件长度; (3)源文件可以进行读写保护。
3.实验提示(1)首先应确定文件系统的数据结构:主目录、子目录及活动文件等。
主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改.(2)用户创建的文件,可以编号存储于磁盘上。
入file0,file1,file2…并以编号作为物理地址,在目录中进行登记。
4.源代码#include<stdio 。
h> #include 〈string.h 〉 #include 〈stdlib 。
h 〉 #define MEM_D_SIZE 1024*1024 //总磁盘空间为1M #define DISKSIZE 1024 //磁盘块的大小1K #define DISK_NUM 1024 //磁盘块数目1K #define FATSIZE DISK_NUM*sizeof (struct fatitem ) //FAT 表大小 #define ROOT_DISK_NO FATSIZE/DISKSIZE+1 //根目录起始盘块号 #define ROOT_DISK_SIZE sizeof (struct direct ) //根目录大小 #define DIR_MAXSIZE 1024 //路径最大长度为1KB #define MSD 5 //最大子目录数5#define MOFN 5//最大文件深度为5#define MAX_WRITE 1024*128//最大写入文字长度128KBstruct fatitem /* size 8*/{int item; /*存放文件下一个磁盘的指针*/char em_disk; /*磁盘块是否空闲标志位 0 空闲*/};struct direct{/*--——-文件控制快信息-—---*/struct FCB{char name[9]; /*文件/目录名 8位*/char property; /*属性 1位目录 0位普通文件*/int size; /*文件/目录字节数、盘块数)*/int firstdisk; /*文件/目录起始盘块号*/int next; /*子目录起始盘块号*/int sign; /*1是根目录 0不是根目录*/}directitem[MSD+2];};struct opentable{struct openttableitem{char name[9]; /*文件名*/int firstdisk; /*起始盘块号*/int size; /*文件的大小*/ }openitem[MOFN];int cur_size; /*当前打文件的数目*/};struct fatitem *fat; /*FAT表*/struct direct *root; /*根目录*/struct direct *cur_dir; /*当前目录*/struct opentable u_opentable; /*文件打开表*/int fd=—1; /*文件打开表的序号*/char *bufferdir; /*记录当前路径的名称*/char *fdisk; /*虚拟磁盘起始地址*/void initfile();void format();void enter();void halt();int create(char *name);int open(char *name);int close(char *name);int write(int fd,char *buf,int len);int read(int fd,char *buf);int del(char *name);int mkdir(char *name);int rmdir(char *name);void dir();int cd(char *name);void print();void show();void initfile(){fdisk = (char *)malloc(MEM_D_SIZE*sizeof (char)); /*申请 1M空间*/format();}void format(){int i;FILE *fp;fat = (struct fatitem *)(fdisk+DISKSIZE); /*计算FAT 表地址,引导区向后偏移 1k)*/ /*————-初始化FAT表-———---——-—-*/fat[0]。
《计算机操作系统》实验指导苏州科技学院电子与信息工程系软件教研室二OO二年九月示例代码第一部分LINUX操作系统平台实验一命令解释程序示例程序minishell.c//文件名minishell.cpp//功能小型SHELL命令解释程序//开发环境#define true 1#define flase 0#include <stdio.h>#include <string.h>#include <stdlib.h>void main(){char cmdl[80];char *scwt[]={"exit","dir","time"};static int cmdnum=3; //可用的命令数char cmd[80];int j,n;while(true){printf("Please input command: ");gets(cmdl); //取命令行输入n=strcspn(cmdl," "); //取命令命令部分if (n>0||strlen(cmdl)>0){ strncpy(cmd,cmdl,n);cmd[n]='\0';for(j=0;j<cmdnum;j++)if (strcmp(cmd,scwt[j])==0)break;if (j==0) //是exit命令?exit(0);if (j<cmdnum) //其他合法命令{system(cmdl);continue;}printf("Bad command!\n"); //命令错}}}实验二进程管理fork()调用示例#include <stdio.h>main(){int p1,p2;while ((p1=fork())==-1);if (p1==0) //是子进程?putchar('b');else //父进程{putchar('a');}}实验三进程间通信1)pipe()调用示例#include<stdio.h>main(){int id,fd[2];char buf[50],s[50];pipe(fd);while ((id=fork())==-1);if (id==0){sprintf(buf,"Child is sending message!");write(fd[1],buf,50);exit(0);}else{wait(0);read(fd[0],s,50);printf("%s\n",s);exit(0);}}2)共享存储器示例shm_sample.c#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#define SEGSIZE 100main(int argc, char *argv[]){ key_t key;int shmid, cntr;char *segptr;if(argc == 1)usage(); /* Create unique key via call to ftok() */key = ftok(".", 'S');/* Open the shared memory segment - create if necessary */if((shmid = shmget(key, SEGSIZE, IPC_CREAT|IPC_EXCL|0666)) == -1){printf("Shared memory segment exists - opening as client\n");/* Segment probably already exists - try as a client */if((shmid = shmget(key, SEGSIZE, 0)) == -1){perror("shmget");exit(1);}}else{printf("Creating new shared memory segment\n");}/* Attach (map) the shared memory segment into the current process */if((segptr = shmat(shmid, 0, 0)) == -1){perror("shmat");exit(1);}switch(tolower(argv[1][0])){case 'w': writeshm(shmid, segptr, argv[2]);break;case 'r': readshm(shmid, segptr);break;case 'd': removeshm(shmid);break;case 'm': changemode(shmid, argv[2]);break;default: usage();}}writeshm(int shmid, char *segptr, char *text){strcpy(segptr, text);printf("Done...\n");}readshm(int shmid, char *segptr){printf("segptr: %s\n", segptr);}removeshm(int shmid){shmctl(shmid, IPC_RMID, 0);printf("Shared memory segment marked for deletion\n");}changemode(int shmid, char *mode){struct shmid_ds myshmds;/* Get current values for internal data structure */shmctl(shmid, IPC_STA T, &myshmds); /* Display old permissions */printf("Old permissions were: %o\n", myshmds.shm_perm.mode);/* Convert and load the mode */sscanf(mode, "%o", &myshmds.shm_perm.mode); /* Update the mode */ shmctl(shmid, IPC_SET, &myshmds);printf("New permissions are : %o\n", myshmds.shm_perm.mode);}usage(){fprintf(stderr, "shm_sample - A utility for tinkering with shared memory\n");fprintf(stderr, "\nUSAGE: shmtool (w)rite <text>\n");fprintf(stderr, " (r)ead\n");fprintf(stderr, " (d)elete\n");fprintf(stderr, " (m)ode change <octal mode>\n");exit(1);}3)消息队列使用示例(1) message.h/* message.h*/#ifndef MESSAGE_H#define MESSAGE_Hstruct mymsgbuf{long mtype;char mtext[256];};#endif(2) msg_server.c/*msg_server.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <sys/msg.h>#include <sys/ipc.h>#include "message.h"int msqid=-1;void sig_handle(int signo){/*软中断*/if (msqid!=-1)msgctl(msqid,IPC_RMID,NULL);printf("server quit...\n");exit(0);}int main(){struct mymsgbuf msgbuf;int left,right;char c;int length;if ((msqid=msgget(999,0666))!=-1){msgctl(msqid,IPC_RMID,NULL);}if ((msqid=msgget(999,IPC_CREAT|0666))==-1){printf("error:getmsg\n");exit(1);}signal(SIGINT,sig_handle); /*LINUX置软中断—CTRL-D*/for (;;){if (msgrcv(msqid,&msgbuf,256,1L,0)==-1){printf("error:msgrcv\n");exit(1);}length=strlen(msgbuf.mtext);left=0;right=length-1;while(left<right){c=msgbuf.mtext[left];msgbuf.mtext[left]=msgbuf.mtext[right];msgbuf.mtext[right]=c;left++;right--;}msgbuf.mtext[length]='\0';msgbuf.mtype=2;if (msgsnd(msqid,&msgbuf,256,0)==-1){printf("error:msgsnd");exit(1);}}msgctl(msqid,IPC_RMID,NULL);exit(0);}(3) msg_client.c/*msg_client.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/msg.h>#include <sys/ipc.h>#include "message.h"int main(){struct mymsgbuf msgbuf;int msqid;if ((msqid=msgget(999,0666))==-1){printf("Server is not running\n");exit(1);}printf("Input a line:");scanf("%s",msgbuf.mtext);msgbuf.mtype=1;if (msgsnd(msqid,&msgbuf,256,0)==-1){printf("error:msgsnd\n");exit(1);}if (msgrcv(msqid,&msgbuf,256,2L,0)==-1){printf("error:msgrcv\n");exit(1);}printf("The reversed line is:%s\n",msgbuf.mtext);exit(0);}实验四存储管理示例程序(注意阅读并分析可能存在的问题)#define TRUE 1#define FALSE 0#define INV ALID -1#define null 0#define total_instruction 320 /*指令流长*/#define total_vp 32 /*虚页长*/#define clear_period 50 /*清零周期*/typedef struct{ /*页面结构*/ int pn,pfn,counter,time;}pl_type;pl_type pl[total_vp]; /*页面数组*/struct pfc_struct{ /*页面控制结构*/ int pn,pfn;struct pfc_struct *next;};typedef struct pfc_struct pfc_type;pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;int diseffect,a[total_instruction];int page[total_instruction], offset[total_instruction];void initialize(int total_pf);void FIFO(int total_pf);void LRU(int total_pf);void OPT(int total_pf);void LFU(int total_pf);void NUR(int total_pf);#include <stdlib.h>#include <stdio.h>#include <time.h>main(){int S,i;srand( (unsigned)time( NULL ) );/* srand(getpid()*10);*//*由于每次运行时进程号不同,故可用来作为初始化随机数的"种子"*/S=(float)319*rand()/32767+1;for(i=0;i<total_instruction;i+=4) /*产生指令队列*/{a[i]=S; /*任选一指令访问点*/a[i+1]=a[i]+1; /*顺序执行一条指令*/a[i+2]=(float)a[i]*rand()/32767; /*执行前地址指令m'*/a[i+3]=a[i+2]+1; /*执行后地址指令*/S=(float)rand()*(318-a[i+2])/32767+a[i+2]+2;}for(i=0;i<total_instruction;i++) /*将指令序列变换成页地址流*/{page[i]=a[i]/10;offset[i]=a[i]%10;}for(i=4;i<=32;i++) /*用户内存工作区从4个页面到32个页面*/ {printf("%2d page frames",i);FIFO(i);LRU(i);OPT(i);LFU(i);NUR(i);printf("\n");}return(0);}//void FIFO(total_pf) /*FIFO(First In First Out) ALOGRITHM*/ //int total_pf; /*用户进程的内存页面数*/void FIFO(int total_pf)//int total_pf;{int i;pfc_type *p;initialize(total_pf);busypf_head=busypf_tail=NULL;for (i=0;i<total_instruction;i++){if (pl[page[i]].pfn==INV ALID){diseffect+=1;if (freepf_head==NULL){p=busypf_head->next;pl[busypf_head->pn].pfn=INV ALID;freepf_head=busypf_head;freepf_head->next=NULL;busypf_head=p;}p=freepf_head->next;freepf_head->next=NULL;freepf_head->pn=page[i];pl[page[i]].pfn=freepf_head->pfn;if (busypf_tail==NULL)busypf_head=busypf_tail=freepf_head;else{busypf_tail->next=freepf_head;busypf_tail=freepf_head;}freepf_head=p;}}printf(" FIFO:%6.4f",1-(float)diseffect/320);}void LRU(int total_pf)//int total_pf;{int min,minj,i,j,present_time;initialize(total_pf);present_time=0;for(i=0;i<total_instruction;i++){if (pl[page[i]].pfn=INV ALID){diseffect++;if (freepf_head==NULL){min=32767;for(j=0;j<total_vp;j++)if (min>pl[j].time && pl[j].pfn!=INV ALID){min=pl[j].time;minj=j;}freepf_head=&pfc[pl[minj].pfn];pl[min].pfn=INV ALID;pl[min].time=-1;freepf_head->next=NULL;}pl[page[i]].pfn=freepf_head->pfn;pl[page[i]].time=present_time;freepf_head=freepf_head->next;}elsepl[page[i]].time=present_time;present_time++;}printf(" LRU:%6.4f",1-(float)diseffect/320);}void NUR(int total_pf)//int total_pf;{int i,j,dp,cont_flag,old_dp;// pfc_type *t;initialize(total_pf);dp=0;for(i=0;i<total_instruction;i++){if (pl[page[i]].pfn==INV ALID) /*页面失效*/{diseffect++;if (freepf_head==NULL) /*无空闲页面*/{cont_flag=TRUE;old_dp=dp;while(cont_flag)if (pl[dp].counter==0&&pl[dp].pfn!=INV ALID)cont_flag=FALSE;else{dp++;if (dp==total_vp)dp=0;if (dp==old_dp)for (j=0;j<total_vp;j++)pl[j].counter=0;}freepf_head=&pfc[pl[dp].pfn];pl[dp].pfn=INV ALID;freepf_head->next=NULL;}pl[page[i]].pfn=freepf_head->pfn;freepf_head=freepf_head->next;}elsepl[page[i]].counter=1;if (i%clear_period==0)for(j=0;j<total_vp;j++)pl[j].counter=0;}printf(" NUR:%6.4f",1-(float)diseffect/320);}void OPT(int total_pf) /*OPT(Optional Replacement) ALOGRITHM*/ //int total_pf;{int i,j,max,maxpage,d,dist[total_vp];pfc_type *t;initialize(total_pf);for(i=0;i<total_instruction;i++){if (pl[page[i]].pfn==INV ALID){diseffect++;if (freepf_head==NULL){for(j=0;j<total_vp;j++)if (pl[j].pfn!=INV ALID)dist[j]=32767;elsedist[j]=0;d=1;for(j=i+1;j<total_instruction;j++){if (pl[page[j]].pfn!=INV ALID)dist[page[j]]=d;d++;}max=-1;for(j=0;j<total_vp;j++)if (max<dist[j]){max=dist[j];maxpage=j;}freepf_head=&pfc[pl[maxpage].pfn];freepf_head->next=NULL;pl[maxpage].pfn=INV ALID;}pl[page[i]].pfn=freepf_head->pfn;freepf_head=freepf_head->next;}}printf(" OPT:%6.4f",1-(float)diseffect/320);}void LFU(int total_pf) /*LFU(leat Frequently Used) ALOGRITHM*/ //int total_pf;{int i,j,min,minpage;pfc_type *t;initialize(total_pf);for(i=0;i<total_instruction;i++){if (pl[page[i]].pfn==INV ALID){diseffect++;if (freepf_head==NULL){min=32767;for(j=0;j<total_vp;j++){if (min>pl[j].counter&&pl[j].pfn!=INV ALID){min=pl[j].counter;minpage=j;}pl[j].counter=0;}freepf_head=&pfc[pl[minpage].pfn];pl[minpage].pfn=INV ALID;freepf_head=freepf_head->next;}elsepl[page[i]].counter++;}}printf(" LFU:%6.4f",1-(float)diseffect/320);}void initialize(int total_pf) /*初始化相关数据结构*///int total_pf; /*用户进程的内存页面数*/{int i;diseffect=0;for(i=0;i<total_vp;i++){pl[i].pn=i;pl[i].pfn=INV ALID; /*置页面控制结构中的页号,页面为空*/pl[i].counter=0; /*页面控制结构中的访问次数为0,时间为-1*/pl[i].time=-1;}for(i=1;i<total_pf;i++){pfc[i-1].next=&pfc[i];pfc[i-1].pfn=i-1;} /*建立pfc[i-1] 和pfc[i]之间的链接*/pfc[total_pf-1].next=NULL;pfc[total_pf-1].pfn=total_pf-1;freepf_head=&pfc[0]; /*空页面队列的头指针为pfc[0]*/}实验五设备管理一、实验步骤:LINUX中,模块可以用C语言编写,用gcc编译成目标文件(不进行链接,作为*.o文件存在),为此需要在gcc命令行里加上-c的参数。
目录实验一WINDOWS进程初识 (2)实验二进程管理 (6)实验三进程同步的经典算法 (10)实验四存储管理 (14)试验五文件系统试验 (18)实验有关(参考)代码实验一WINDOWS进程初识1、实验目的(1)学会使用VC编写基本的Win32 Consol Application(控制台应用程序)。
(2)掌握WINDOWS API的使用方法。
(3)编写测试程序,理解用户态运行和核心态运行。
2、程序清单清单1-1 一个简单的Windows控制台应用程序// hello项目# include <iostream>void main(){std::cout << “Hello, Win32 Consol Application” << std :: endl ;}清单1-2 核心态运行和用户态运行时间比计算// proclist项目# include <windows.h># include <tlhelp32.h># include <iostream.h>// 当在用户模式机内核模式下都提供所耗时间时,在内核模式下进行所耗时间的64位计算的帮助方法DWORD GetKernelModePercentage(const FILETIME& ftKernel,const FILETIME& ftUser){// 将FILETIME结构转化为64位整数ULONGLONG qwKernel=(((ULONGLONG)ftKernel.dwHighDateTime)<<32)+ftKernel.dwLowDateTime;ULONGLONG qwUser=(((ULONGLONG)ftUser.dwHighDateTime)<<32)+ftUser.dwLowDateTime;// 将消耗时间相加,然后计算消耗在内核模式下的时间百分比ULONGLONG qwTotal=qwKernel+qwUser;DWORD dwPct=(DWORD)(((ULONGLONG)100*qwKernel)/qwTotal);return(dwPct);}// 以下是将当前运行过程名和消耗在内核模式下的时间百分数都显示出来的应用程序void main(int argc,char *argv[]){if(argc<2){cout<<"请给出你要查询的程序名"<<endl;exit(0);}// 对当前系统中运行的过程拍取“快照”HANDLE hSnapshot=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,// 提取当前过程0);// 如果是当前过程,就将其忽略// 初始化过程入口PROCESSENTRY32 pe;::ZeroMemory(&pe,sizeof(pe));pe.dwSize=sizeof(pe);BOOL bMore=::Process32First(hSnapshot,&pe);BOOL found = FALSE;while(bMore){// 打开用于读取的过程if(!strcmp(pe.szExeFile,argv[1])){found = TRUE;HANDLE hProcess=::OpenProcess(PROCESS_QUERY_INFORMA TION,// 指明要得到信息FALSE,// 不必继承这一句柄pe.th32ProcessID);// 要打开的进程if (hProcess!=NULL){// 找出进程的时间FILETIME ftCreation,ftKernelMode,ftUserMode,ftExit;::GetProcessTimes(hProcess,// 所感兴趣的进程&ftCreation,// 进程的启动时间&ftExit,// 结束时间(如果有的话)&ftKernelMode,// 在内核模式下消耗的时间&ftUserMode);// 在用户模式下消耗的时间// 计算内核模式消耗的时间百分比DWORD dwPctKernel=::GetKernelModePercentage(ftKernelMode,// 在内核模式上消耗的时间ftUserMode);// 在用户模式下消耗的时间// 向用户显示进程的某些信息cout<< "process ID: " << pe.th32ProcessID<< ",EXE file:" << pe.szExeFile<< ",%d in Kernel mode: " << dwPctKernel << endl;// 消除句柄::CloseHandle(hProcess);}}// 转向下一个进程bMore=::Process32Next(hSnapshot,&pe);}if(found==FALSE){cout<<"当前系统没有这个可执行程序正在运行"<<endl;exit(0);}}清单1-3 核心态运行和用户态运行时间测试程序#include <stdio.h>main(){int i,j;while(1){for(i=0;i<1000;i++);for(j=1;j<1000;j++) printf(“enter kernel mode running.”);}}实验二进程管理1、实验目的1) 通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows进程的“一生”。
操作系统上机实验代码修改后的md命令程序:int MdComd(int k) //md命令处理函数{// 命令形式:md <目录名>// 功能:在指定路径下创建指定目录,若没有指定路径,则在当前目录下创建指定目录。
// 对于重名目录给出错误信息。
目录与文件也不能重名。
// 学生可以考虑命令中加“属性”参数,用于创建指定属性的子目录。
命令形式如下:// md <目录名>[ <属性>]// 属性包括R、H、S以及它们的组合(不区分大小写,顺序也不限)。
例如:// md user rh// 其功能是在当前目录中创建具有“只读”和“隐藏”属性的子目录user。
short i,s,s0,kk;char attrib=(char)16,*DirName;FCB *p;char str[20]="|";kk=SIZE/sizeof(FCB);if (k<1){cout<<"\错误:命令中没有目录名。
\";return -1;}if (k>2){cout<<"\错误:命令参数太多。
\";return -1;}s=ProcessPath(comd[1],DirName,k,0,attrib);if (s<0)return s; //失败,返回if (!IsName(DirName)) //若名字不符合规则{cout<<"\命令中的新目录名错误。
\";return -1;}i=FindFCB(DirName,s,attrib,p);if (i>0){cout<<"\错误:目录重名!\";return -1;}if (k==2) //命令形式:md <目录名> <属性符>{i=GetAttrib(strcat(str,comd[2]),attrib);//由i=GetAttrib(comd[2],attrib);if (i<0)return i;}s0=FindBlankFCB(s,p);//找空白目录项if (s0<0) //磁盘满return s0;s0=M_NewDir(DirName,p,s,attrib); //在p所指位置创建一新子目录项if (s0<0) //创建失败{cout<<"\磁盘空间已满,创建目录失败。
#include <iostream.h>#include <windows.h>//三种模式void filter_nobuffer(char* source,char* sink,void (*func)(char* addr));void filter_sequen(char* source,char* sink,void (*func)(char* addr));void filter_overlp(char* source,char* sink,void (*func)(char* addr));//五个不同功能的操作void f1(char* addr);void f2(char* addr);void f3(char* addr);void f4(char* addr);void f5(char* addr);#define BUFFER_SIZE 1024 //定义缓冲区的大小,这里设为1024字节char * buffer; //这里的缓冲区被定义成char型void main(){//分配缓冲区buffer = new char[BUFFER_SIZE];//用于记录执行filter函数的开始时间DWORD tick;//用于求三种模式各自的平均用时DWORD nobuffer_average_time=0;DWORD sequen_average_time=0;DWORD overlp_average_time=0;//采用无缓存模式调用filter函数10次cout<<"☆无文件高速缓存模式正在运行……"<<endl;DWORD nobuffer_start_time=GetTickCount();tick = nobuffer_start_time;filter_nobuffer("source.txt","nobuffer_1.txt",f1);cout<<"nobuffer 0-1: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_1.txt","nobuffer_2.txt",f2);cout<<"nobuffer 1-2: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_2.txt","nobuffer_3.txt",f3);cout<<"nobuffer 2-3: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_3.txt","nobuffer_4.txt",f4);cout<<"nobuffer 3-4: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_4.txt","nobuffer_5.txt",f5);tick = GetTickCount();filter_nobuffer("nobuffer_5.txt","nobuffer_6.txt",f1);cout<<"nobuffer 5-6: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_6.txt","nobuffer_7.txt",f2);cout<<"nobuffer 6-7: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_7.txt","nobuffer_8.txt",f3);cout<<"nobuffer 7-8: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_8.txt","nobuffer_9.txt",f4);cout<<"nobuffer 8-9: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_9.txt","nobuffer_10.txt",f5);DWORD nobuffer_end_time=GetTickCount();cout<<"nobuffer 9-10: "<<nobuffer_end_time - tick<<" ms."<<endl<<endl; //采用高速缓存模式调用filter函数10次cout<<"★使用文件高速缓存模式正在运行……"<<endl;DWORD sequen_start_time=GetTickCount();tick = sequen_start_time;filter_sequen("source.txt","sequen_1.txt",f1);cout<<"sequen 0-1: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_1.txt","sequen_2.txt",f2);cout<<"sequen 1-2: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_2.txt","sequen_3.txt",f3);cout<<"sequen 2-3: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_3.txt","sequen_4.txt",f4);cout<<"sequen 3-4: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_4.txt","sequen_5.txt",f5);cout<<"sequen 4-5: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_5.txt","sequen_6.txt",f1);cout<<"sequen 5-6: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_6.txt","sequen_7.txt",f2);cout<<"sequen 6-7: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_7.txt","sequen_8.txt",f3);tick = GetTickCount();filter_sequen("sequen_8.txt","sequen_9.txt",f4);cout<<"sequen 8-9: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_9.txt","sequen_10.txt",f5);DWORD sequen_end_time=GetTickCount();cout<<"sequen 9-10: "<<sequen_end_time - tick<<" ms."<<endl<<endl; //采用异步模式调用filter函数10次cout<<"◎异步传输模式正在运行……"<<endl;DWORD overlp_start_time=GetTickCount();tick = overlp_start_time;filter_overlp("source.txt","overlp_1.txt",f1);cout<<"overlp 0-1: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_1.txt","overlp_2.txt",f2);cout<<"overlp 1-2: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_2.txt","overlp_3.txt",f3);cout<<"overlp 2-3: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_3.txt","overlp_4.txt",f4);cout<<"overlp 3-4: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_4.txt","overlp_5.txt",f5);cout<<"overlp 4-5: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_5.txt","overlp_6.txt",f1);cout<<"overlp 5-6: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_6.txt","overlp_7.txt",f2);cout<<"overlp 6-7: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_7.txt","overlp_8.txt",f3);cout<<"overlp 7-8: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_8.txt","overlp_9.txt",f4);cout<<"overlp 8-9: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_9.txt","overlp_10.txt",f5);DWORD overlp_end_time=GetTickCount();cout<<"overlp 9-10: "<<overlp_end_time - tick<<" ms."<<endl<<endl;//输出三种模式下的平均时间以做对比cout<<"■三种模式的平均用时如下:"<<endl;cout<<"·无文件高速缓存模式平均用时:"<<(nobuffer_end_time-nobuffer_start_time)/10<<" ms."<<endl;cout<<"·使用文件高速缓存模式平均用时:"<<(sequen_end_time-sequen_start_time)/10<<" ms."<<endl;cout<<"·异步传输模式平均用时:"<<(overlp_end_time-overlp_start_time)/10<<" ms."<<endl<<endl;return;}//对文件内容进行的5种操作(可以任意定义),本程序仅用了五个很简单的操作//f1 +1//f2 -1//f3 *1//f4 >>//f5 <<void f1(char* addr){ *addr = (unsigned char)*addr + 1; }void f2(char* addr){ *addr = (unsigned char)*addr - 1; }void f3(char* addr){ *addr = (unsigned char)*addr * 1; }void f4(char* addr){ *addr = (unsigned char)*addr >> 1;}void f5(char* addr){ *addr = (unsigned char)*addr << 1;}//没有文件高速缓存的filter函数void filter_nobuffer(char* source, char* sink, void (*func) (char* addr)){HANDLE handle_src,handle_dst; //定义源文件与目标文件的句柄BOOL cycle; //用以判断是否满一个缓冲区DWORD NumberOfBytesRead,NumberOfBytesWrite,index; //读的字节数、写的字节数//打开源文件handle_src=CreateFile(source,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG _NO_BUFFERING,NULL);//创建目标文件handle_dst = CreateFile(sink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NULL);//如果打开或创建失败,则报错if( handle_src == INVALID_HANDLE_VALUE || handle_dst == INVALID_HANDLE_VALUE){cout<<"CreateFile Invocation Error!"<<endl;exit(1);}cycle = TRUE;//用cycle判断文件什么时候读完while(cycle){//从源文件读数据送入缓冲区if(ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL) == FALSE){cout<<"ReadFile Error!"<<endl;exit(1);}//当读不满一个缓冲区时,说明达到文件末尾,结束循环if(NumberOfBytesRead < BUFFER_SIZE)cycle = FALSE;//对文件内容进行的操作for(index = 0;index < NumberOfBytesRead;index++)func(&buffer[index]);//将缓冲区中的数据写入目标文件if(WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL) == FALSE){cout<<"WriteFile Error!"<<endl;exit(1);}}//关闭文件句柄CloseHandle(handle_src);CloseHandle(handle_dst);}void filter_sequen(char* source, char* sink, void (*func) (char* addr)){HANDLE handle_src,handle_dst; //定义源文件与目标文件的句柄BOOL cycle; //用以判断是否满一个缓冲区DWORD NumberOfBytesRead,NumberOfBytesWrite,index; //读的字节数、写的字节数//CreateFile函数设置参数FILE_FLAG_SEQUENTIAL_SCAN:使用文件高速缓存//打开源文件handle_src=CreateFile(source,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG _SEQUENTIAL_SCAN,NULL);//创建目标文件handle_dst=CreateFile(sink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_FLAG _SEQUENTIAL_SCAN,NULL);//如果打开或创建失败,则报错if( handle_src == INVALID_HANDLE_VALUE || handle_dst ==INVALID_HANDLE_VALUE){cout<<"CreateFile Invocation Error!"<<endl;exit(1);}cycle = TRUE;//用cycle判断文件什么时候读完while(cycle){//从源文件读数据送入缓冲区if(ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL)==FALSE) {cout<<"ReadFile Error!"<<endl;exit(1);}//当读不满一个缓冲区时,说明达到文件末尾,结束循环if(NumberOfBytesRead < BUFFER_SIZE)cycle = FALSE;//对文件内容进行的操作for(index = 0;index < NumberOfBytesRead;index++)func(&buffer[index]);//将缓冲区中的数据写入目标文件if(WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL) == FALSE){cout<<"WriteFile Error!"<<endl;exit(1);}}//关闭文件句柄CloseHandle(handle_src);CloseHandle(handle_dst);}void filter_overlp(char* source, char* sink, void (*func) (char* addr)){HANDLE handle_src,handle_dst; //定义源文件与目标文件的句柄BOOL cycle; //用以判断是否满一个缓冲区//读的字节数、写的字节数、GetLastError函数的返回值DWORD NumberOfBytesRead,NumberOfBytesWrite,index,dwError; OVERLAPPED overlapped; //overlapped 结构//打开源文件handle_src=CreateFile(source,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,NULL);//创建目标文件handle_dst=CreateFile(sink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NUL L);//如果打开或创建失败,则报错if( handle_src == INVALID_HANDLE_VALUE || handle_dst == INVALID_HANDLE_VALUE){cout<<"CreateFile Invocation Error"<<endl;exit(1);}//对overlapped结构初始化overlapped.hEvent=NULL;overlapped.Offset=-BUFFER_SIZE;overlapped.OffsetHigh=0;cycle = TRUE;//用cycle判断文件什么时候读完while(cycle){//计算文件的偏移量overlapped.Offset = overlapped.Offset + BUFFER_SIZE;//读源文件if(ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,&overlapped) == FALSE){switch(dwError = GetLastError()){//读到文件结尾case ERROR_HANDLE_EOF:cycle = FALSE;break;//异步传输正在进行case ERROR_IO_PENDING:if(GetOverlappedResult(handle_src,&overlapped,&NumberOfBytesRead,TRUE) == FALSE){cout<<"GetOverlappedResult Error!"<<endl;exit(1);}break;default:break;}}//当读不满一个缓冲区时,说明达到文件末尾,结束循环if(NumberOfBytesRead < BUFFER_SIZE)cycle = FALSE;//对文件内容进行的操作for(index = 0;index < NumberOfBytesRead;index++)func(&buffer[index]);//将缓冲区中的数据写入目标文件if(WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite, NULL) == FALSE){cout<<"WriteFile Error!"<<endl;exit(1);}}//关闭文件句柄CloseHandle(handle_src);CloseHandle(handle_dst);}。
#define false 0#define true 1#include "stdio.h"typedef struct{char name[3]; /*文件或目录名*/char type[2]; /*文件类型名*/char attribute; /*属性*/char address; /*文件或目录的起始盘块号*/char length; /*文件长度,以盘块为单位*/}content; /*目录结构*/#define n 5 /*模拟实验中系统允许打开文件的最大数量*/typedef struct{int dnum; /*磁盘盘块号*/int bnum; /*盘块内第几项*/}pointer; /*已打开文件表中读写指针的结构*/typedef struct{char name[20]; /*文件绝对路径名*/char attribute;/*文件的属性,用1个字节表示,所以用了char类型*/int number; /*文件起始盘块号*/int length; /*文件长度,文件占用的字节数*/int flag; /*操作类型,用"0"表示以读操作方式开文件,用"1"表示写操作方式打开文件*/ pointer read; /*读文件的位置,文件刚打开时dnum为文件起始盘块号,bnum为"0"*/ pointer write; /*写文件的位置,文件建立时dnum为文件起始盘块号,bnum为"0",打开时为文件末尾*/}OFILE; /*已打开文件表项类型定义*/struct{OFILE file[n]; /*已打开文件表*/int length; /*已打开文件表中登记的文件数量*/}openfile; /*已打开文件表定义*/char buffer1[64];/*模拟缓冲1*/content buffer2[8];/*模拟缓冲2*/FILE *fc; /*模拟磁盘的文件指针*/void copen(OFILE *x1,OFILE *x2)OFILE *x1,*x2;{strcpy(x1->name,x2->name);x1->attribute=x2->attribute;x1->number=x2->number;x1->length=x2->length;x1->flag=x2->flag;x1->read.dnum=x2->read.dnum;x1->read.bnum=x2->read.bnum;x1->write.dnum=x2->write.dnum;x1->write.bnum=x2->write.bnum;}sopen(name)/*在已打开文件表中查找文件name*/char *name;{int i;i=0;while(i<openfile.length&&strcmp(openfile.file[i].name,name)!=0)/*依次查找已打开文件表*/i++;if(i>=openfile.length)return(-1);return(i);}/*查找sopen函数结束*/dopen(name)/*在已打开文件表中删除文件name*/char *name;{int i;i=sopen(name);if(i==-1)printf("文件未打开/n");else{copen(&openfile.file[i],&openfile.file[openfile.length-1]);openfile.length--;}}/*删除函数结束*/iopen(x)/*在已打开文件表中插入文件name*/content *x;{int i;i=sopen(x->name);if(i!=-1){printf("文件已经打开/n");return(false);}else if(openfile.length==n){printf("已打开文件表已满/n");return(false);}else{copen(&openfile.file[openfile.length],x);openfile.length++;return(true);}}/*填写已打开文件表函数结束*/allocate( )/*分配一个磁盘块,返回块号*/{int i;fseek(fc,0,SEEK_SET); /*将模拟磁盘的文件指针移至模拟磁盘FAT表*/fread(buffer1,64L,1,fc);/*将FAT表中第一个磁盘块读入模拟缓冲buffer1中*/for(i=3;i<63;i++)if(buffer1[i]==0){ /*FAT中的第i项为0,分配第i块磁盘块,修改FAT表,并且写回磁盘*/buffer1[i]=255;fseek(fc,0,SEEK_SET);fwrite (buffer1,64L,1,fc);return(i); /*返回磁盘号*/}fread(buffer1,64L,1,fc);/*将FAT表中第二个磁盘块读入模拟缓冲buffer1中*/for(i=0;i<63;i++)if(buffer1[i]==0){/*FAT中的第i项为0,分配第i+64块磁盘块,修改FAT表,并且写回磁盘*/ buffer1[i]=255;fseek(fc,-64L,SEEK_CUR);fwrite(buffer1,64L,1,fc);return(i+64); /*返回磁盘号*/}printf("已经没有磁盘空间/n");return(false);}/*分配磁盘块函数结束*/read_file(name,length)/*读文件函数,文件路径名name,读取长度length*/char *name;int length;{int i,t;char ch;if((i=sopen(name))==-1){printf("文件没有打开或不存在/n");return(false);}if(openfile.file[i].flag==1){printf("文件以写方式打开,不能读/n");return(false);}t=0;fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET);fread(buffer1,64,1,fc);while(t<length&&buffer1[openfile.file[i].read.bnum]!='#'){putchar(buffer1[openfile.file[i].read.bnum]);/*读出一个字符(这里是在屏幕上显示)*/if((t+1)%64==0)putchar('/n');/*修改读指针*/openfile.file[i].read.bnum++;if(openfile.file[i].read.bnum>=64)/*一块读完,读取下一个盘块*/{fseek(fc,openfile.file[i].read.dnum/64*64, SEEK_SET);fread(buffer1,64,1,fc);openfile.file[i].read.dnum=buffer1[openfile.file[i].read.dnum%64];/*修改读指针*/openfile.file[i].read.bnum=0;fseek(fc,openfile.file[i].read.dnum*64L,SEEK_SET);fread(buffer1,64,1,fc);/*读取下一个*/}t++;}}/*读函数结束*/write_file(name,buff,length)/*写文件函数*/char *name;/*文件路径名*/char *buff;/*存放准备写入磁盘的内容*/int length;/*写入内容的长度*/{int i,t,dd;if((i=sopen(name))==-1)/*文件不存在,无法写*/{printf("文件没有打开或不存在/n");return(false);}if(openfile.file[i].flag==0){printf("文件以读方式打开,不能写/n");return(false);}t=0;fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET);fread(buffer1,64,1,fc);while(t<length){buffer1[openfile.file[i].write.bnum]=buff[t];openfile.file[i].write.bnum++;openfile.file[i].length++;if(openfile.file[i].write.bnum>=64){fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET);fwrite(buffer1,64,1,fc);/*一块写完,写回磁盘*/if((dd=allocate())==false){openfile.file[i].write.bnum--;openfile.file[i].length--;printf("无磁盘空间,部分信息丢失,写失败/n");return(false);}/*if*/fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET);fread(buffer1,64,1,fc);buffer1[openfile.file[i].write.dnum%64]=dd;fseek(fc,openfile.file[i].write.dnum/64*64L, SEEK_SET);fwrite(buffer1,64,1,fc);openfile.file[i].write.dnum=dd;openfile.file[i].write.bnum=0;}/*if*/t++;}/*while*/fseek(fc, openfile.file[i].write.dnum*64L, SEEK_SET);fwrite(buffer1,64,1,fc);/*一块写完,写回磁盘*/}/*写函数结束*/search(name,flag,dnum,bnum)/*查找路径名为name的文件或目录,返回该目录的起始盘块号*/char *name;int flag; /*flag=8表示查找目录,否则为文件*/int *dnum,*bnum;/*返回找到文件或目录的目录项的位置:盘块dnum中第bnum项*/ {int k,i,s,t,j,last=0;char pna[3],type[2];if((strcmp(name,"")==0)||(strcmp(name,"/")==0))/*根目录*/return(2);k=0;if(name[0]=='/')k=1;i=2; /*i=根目录的起始盘块号*/while(last!=1){/*pna=从name中分离出"/"后一个目录名(或文件名)*/for(s=0;name[k]!='.'&&name[k]!='/'&&s<3&&name[k]!='/0';s++,k++)pna[s]=name[k];for(;s<3;s++)/*用空格补全名字长度*/pna[s]=' ';while(name[k]!='.'&&name[k]!='/0'&&name[k]!='/')/*除去多余字符*/k++;type[0]=type[1]=' ';if(name[k]=='.')/*取文件类型名type*/if(flag==8){printf("目录不应该有有类型名,查找失败/n");return(false);}else{/*文件遇到类型名认为结束,后面的字符作废*/k++;if(name[k]!='/0')type[0]=name[k];k++;if(name[k]!='/0')type[1]=name[k];if(name[k]!='/0'&&name[k+1]!='/0'){printf("文件名错误/n");return(false);}last=1;}elseif(name[k]!='/0')k++;if(name[k]=='/0')last=1;/*查找目录且名字等于pna的目录项*/fseek(fc,i*64L,SEEK_SET);fread(buffer2,64L,1,fc);j=0;if(last==1&&flag!=8)while(j<8&&!(buffer2[j].attribute!=8&&buffer2[j].name[0]==pna[0]&&buffer2[j].name[1]==pna[1]&&buffer2[j].name[2]==pna[2]&&buffer2[j].type[0]==type[0]&&buffer2[j].type[1]==type[1]))j++;elsewhile(j<8&&!(buffer2[j].attribute==8&&buffer2[j].name[0]==pna[0]&&buffer2[j].name[1]= =pna[1]&&buffer2[j].name[2]==pna[2]))j++;if(j<8)/*找到该目录或文件*/if(last==1)/*查找结束*/{*dnum=i;*bnum=j;return(buffer2[j].address);}else/*查找还未结束*/i=buffer2[j].address;/*读取下一个盘块*/elsereturn(false);}/*while 查找结束*/}/*search()结束*/create_file(name,attribute)/*建立文件函数,路径名name,文件属性attribute*/char *name;int attribute;{int dnum,bnum,i,j,last,k,s,d,t,tt,b,dd,flag,dn,bn;char dname[3],tname[2],pathname[20];OFILE x;if(attribute%2==1){printf("只读文件,无法写,不能建立/n");return(false);}if(openfile.length==n){printf("已打开表已满,不能建立/n");return(false);}/* 将name分成两部分,目录路径pathname和目录名dname*/for(j=0;name[j]!='/0';j++)/*查找最后一个"/"*/if(name[j]=='/')s=j;/*分离目录路径*/for(j=0;j<s;j++)pathname[j]=name[j];pathname[j]='/0';/*分离文件名*/for(k=0,j=s+1;name[j]!='/0'&&k<3&&name[j]!='.';j++,k++)dname[k]=name[j];if(k==0){printf("错误文件名或目录名/n");return(false);}for(;k<3;k++)dname[k]=' ';k=0;if(name[j++]=='.')/*分离类型名*/{for(;name[j]!='/0'&&k<2&&name[j]!='.';j++,k++)tname[k]=name[j];}for(;k<2;k++)tname[k]=' ';if((d=search(pathname,8,&dn,&bn))==false)/*找到目录路径,返回该目录所在块号dn 和项数bn*/{printf("目录不存在,不能建立");return(false);}/*确认该目录不存在的同时查找空目录项*/b=-1;fseek(fc,d*64L,SEEK_SET);fread(buffer2,64L,1,fc); /*读出dnum盘块的内容*/for(t=0;t<8;t++){if(buffer2[t].name[0]==dname[0]&&buffer2[t].name[1]==dname[1]&&buffer2[t].name[2]== dname[2]&&buffer2[t].type[0]==tname[0]&&buffer2[t].type[1]==tname[1]){/*找到名字dname的文件,建立失败*/printf("文件已经存在,不能建立/n");return(false);}if(buffer2[t].name[0]=='$'&&b==-1)b=t;}/*for*/if(b==-1)/*没有空目录项,建立失败*/{printf("目录无空间/n");return(false);}if((dd=allocate( ))==false)/*分配给建立目录的磁盘盘块dd*/{printf("建立文件失败/n");return(false);}/*填写目录项*/for(i=0;i<3;i++)buffer2[b].name[i]=dname[i];for(i=0;i<2;i++)buffer2[b].type[i]=tname[i];buffer2[b].attribute=attribute;buffer2[b].address=dd;buffer2[b].length=0;fseek(fc,d*64L,SEEK_SET);fwrite(buffer2,64L,1,fc);/*填写已打开文件表*/strcpy(,name);x.attribute=attribute;x.number=dd;x.length=0;x.flag=1;x.read.dnum=x.write.dnum=dd;x.read.bnum=x.write.bnum=0;iopen(&x);}/*建立文件结束*/open_file(name,attribute)/*打开文件函数*/char *name;int attribute;{OFILE x;int dnum,bnum,last,i,d;if((d=search(name,4,&dnum,&bnum))==false){printf("文件不存在,打开操作失败/n");return(false);}fseek(fc,dnum*64L,SEEK_SET);/*读出对应目录项*/fread(buffer2,64,1,fc);if((buffer2[bnum].attribute%2==1)&& attribute==1)/*对只读文件要求写*/ {printf("文件不能写,打开失败");return(false);}strcpy(,name);x.attribute=buffer2[bnum].attribute;x.number=buffer2[bnum].address;x.read.dnum=x.write.dnum=buffer2[bnum].address;x.read.bnum=x.write.bnum=0;x.flag=attribute;if(attribute==1){while(d!='/xff')/*寻找文件末尾*/{fseek(fc, d/64*64L, SEEK_SET);fread(buffer1,64L,1,fc);/*读出dnum项所在FAT*/last=d;d=buffer1[d%64];/*读出dnum块下一块内容赋给dnum*/ }/*while*/x.write.dnum=last;/*填写写指针*/fseek(fc, last*64L, SEEK_SET);fread(buffer1,64L,1,fc);for(i=0;i<64&&buffer1[i]!='#';i++);x.write.bnum=i;x.length=(buffer2[bnum].length-1)*64+i;}iopen(&x);/*填写已打开文件表*/}close_file(name)/*关闭文件函数*/char *name;{int i,dnum,bnum;if((i=sopen(name))==-1){printf("打开的文件中没有该文件,关闭失败/n");return(false);}if(openfile.file[i].flag==1)/*写文件的追加文件结束符*/{fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET);fread(buffer1,64,1,fc);buffer1[openfile.file[i].write.bnum]='#';fseek(fc,openfile.file[i].write.dnum*64L, SEEK_SET);fwrite(buffer1,64,1,fc);fputc('#',fc);search(name,4,&dnum,&bnum);/*查找该文件目录位置*//*修改目录中的文件长度*/fseek(fc,dnum*64L, SEEK_SET);fread(buffer2,64,1,fc);buffer2[bnum].length=openfile.file[i].length/64+1;fseek(fc, dnum*64L, SEEK_SET);fwrite(buffer2,64,1,fc);}/*在已打开文件表中删除该文件的登记项*/if(openfile.length>1)copen(&openfile.file[i],&openfile.file[openfile.length-1]);openfile.length--;}delete(name)/*删除文件*/char *name;{int dnum,bnum,t;if((t=search(name,4,&dnum,&bnum))==false){printf("文件不存在/n");return(false);}if(sopen(name)!=-1){printf("该文件打开,不能删除/n");return(false);}fseek(fc,dnum*64L, SEEK_SET);fread(buffer2,64,1,fc);buffer2[bnum].name[0]='$';/*将该文件的目录置成空目录*/fseek(fc,dnum*64L, SEEK_SET);fwrite(buffer2,64,1,fc);while(t!='/xff')/*通过FAT查找每一个盘块号,并依次删除*/{dnum=t;fseek(fc, dnum/64*64, SEEK_SET);fread(buffer1,64,1,fc);t=buffer1[dnum%64];buffer1[dnum%64]=0;fseek(fc, dnum/64*64L, SEEK_SET);fwrite(buffer1,64,1,fc);}}/*文件删除结束*/md(name)/*建立目录函数,目录路径名name*/char *name;{int dnum,bnum,i,j,last,k,s,d,t,tt,b,dd,flag,dn,bn;char dname[3],pathname[20];i=2;/* i=根目录的起始盘块号*//* 将name分成两部分,目录路径pathname和目录名dname*/ for(j=0;name[j]!='/0';j++)/*查找最后一个"/"*/if(name[j]=='/')s=j;/*分离目录路径*/for(j=0;j<s;j++)pathname[j]=name[j];pathname[j]='/0';/*分离目录名*/for(k=0,j=s+1;name[j]!='/0'&&k<3&&name[j]!='.';j++,k++) dname[k]=name[j];if(k==0){printf("错误文件名或目录名/n");return(false);}for(;k<3;k++)dname[k]=' ';if((d=search(pathname,8,&dn,&bn))==false)/*找到目录路径*/{printf("目录不存在,不能建立/n");return(false);}b=-1;/*确认该目录不存在的同时查找空目录项*/fseek(fc,d*64L,SEEK_SET);fread(buffer2,64L,1,fc);/*读出d盘块的内容*/for(t=0;t<8;t++){if(buffer2[t].name[0]==dname[0]&&buffer2[t].name[1]==dname[1] &&buffer2[t].name[2]==dname[2]&&buffer2[t].attribute==8) {/*找到名字dname的目录,建立失败*/printf("目录已经存在,不能建立/n");return(false);}if(buffer2[t].name[0]=='$'&&b==-1)b=t;}/*for*/if(b==-1)/*没有空目录项,不能建立*/{printf("目录无空间/n");return(false);}if((dd=allocate( ))==false)/*分配给建立目录的磁盘盘块dd*/{printf("目录不能建立/n");return(false);}/*填写目录项*/for(i=0;i<3;i++)buffer2[b].name[i]=dname[i];buffer2[b].type[0]=buffer2[b].type[1]=' ';buffer2[b].attribute=8;buffer2[b].address=dd;buffer2[b].length=0;fseek(fc,d*64L,SEEK_SET);fwrite(buffer2,64L,1,fc);/*分给新建目录的盘块初始化*/for(t=0;t<8;t++)buffer2[t].name[0]='$';fseek(fc, dd*64L, SEEK_SET);fwrite(buffer2,64L,1,fc);}/*建立目录结束*/dir(name)/*显示目录内容*/char *name;{int i,bnum,t,tt,dnum,dn,bn;if((dnum=search(name,8,&dn,&bn))==false)/*找到目录路径,返回该目录所在块号dn和盘块内项数bn*/{printf("目录不存在/n");return(false);}printf("名称扩展名起始盘块长度/n");/*显示目录内容*/fseek(fc,dnum*64L, SEEK_SET);fread(buffer2,64L,1,fc);for(t=0;t<8;t++)/*显示该盘块中目录项的内容*/if(buffer2[t].name[0]!='$')printf(" %c%c%c %c%c %4d%7d/n", buffer2[t].name[0], buffer2[t].name[1],buffer2[t].name[2], buffer2[t].type[0], buffer2[t].type[1],buffer2[t].address, buffer2[t].length);}/*显示目录函数结束*/typefile(name)/*显示文件内容*/char *name;{int i,dnum,dn,bn,t;if((dnum=search(name,1,&dn,&bn))==false){printf("文件不存在/n");return(false);}if(sopen(name)!=-1){printf("该文件打开,不能显示/n");return(false);}while(dnum!='/xff'){fseek(fc,dnum*64L,SEEK_SET);fread(buffer1,64,1,fc);/*读一个盘块到缓冲*/for(t=0;t<64&&buffer1[t]!='#';t++)/*显示缓冲中内容*/ putchar(buffer1[t]);printf("/n");/*获得下一个盘块*/fseek(fc, dnum/64*64L, SEEK_SET);fread(buffer1,64,1,fc);dnum=buffer1[dnum%64];}}/*显示文件函数结束*/change(name,attribute)/*改变文件name的属性为attribute*/char *name;int attribute;{int dnum,bnum;if(search(name,1,&dnum,&bnum)==false)/*查找文件目录*/ {printf("文件不存在/n");return(false);}if(sopen(name)!=-1){printf("该文件打开,不能改变文件属性/n");return(false);}fseek(fc,dnum*64L,SEEK_SET);fread(buffer2,64,1,fc);/*读出该目录所在盘块*/buffer2[bnum].attribute=attribute;/*修改属性*/fseek(fc,dnum*64L,SEEK_SET);fwrite(buffer2,64,1,fc);/*写回磁盘*/}/*改变文件属性函数结束*/main( ){char name[20];int attribute,type,length,i,a,j;char buffer[64];/*建立文件,模拟磁盘*/if((fc=fopen("c://os//c","w+"))==NULL){printf("无法打开文件/n");exit(0);}/*初始化已打开文件表*/openfile.length=0;/*初始化磁盘*//*初始化文件分配表*/buffer1[0]=buffer1[1]=buffer1[2]=255;/*磁盘第0、1块存放FAT表,第2块存放跟目录*/for(i=3;i<64;i++)buffer1[i]=0;buffer1[13]=buffer1[49]=254;/*假定模拟磁盘中有两个坏盘块:第13块和49块*/fwrite(buffer1,64L,1,fc);for(i=0;i<64;i++)buffer1[i]=0;fwrite(buffer1,64L,1,fc);/*初始化根目录*/for(i=0;i<8;i++)buffer2[i].name[0]='$';/*若目录项的第一个字符为"$"表示该目录项为空*/ fwrite(buffer2,64L,1,fc);/*初始化已打开文件表*/while(1){printf("/n 0 - 结束/n");printf(" 1 - 建立文件/n");printf(" 2 - 打开文件/n");printf(" 3 - 读文件/n");printf(" 4 - 写文件/n");printf(" 5 - 关闭文件/n");printf(" 6 - 删除文件/n");printf(" 7 - 建立目录/n");printf(" 8 - 显示目录内容/n");printf(" 9 - 显示文件内容/n");printf(" 10 - 改变文件属性/n");printf(" 选择功能项(0~9):");scanf("%d",&a);switch(a){case 0: /*a=0程序结束*/fclose(fc);exit(0);case 1: /*a=1建立文件*/printf("输入文件路径名和文件属性(1-只读文件,3-只读系统文件,4-普通文件):");scanf("%s%d",name,&attribute);create_file(name,attribute); /*建立文件*/break;case 2: /*a=2打开文件*/printf("输入文件路径名和操作类型(0-读文件,1-写文件):");scanf("%s%d",name,&type);open_file(name,type); /*打开文件*/break;case 3: /*a=3读文件*/printf("输入文件路径名和读长度");scanf("%s%d",name,&length);read_file(name,length); /*读文件*/break;case 4: /*a=4写文件*/printf("输入文件路径名:");scanf("%s",name);printf("输入写的内容和和写长度");scanf("%s%d",buffer,&length);write_file(name,buffer,length); /*写文件*/break;case 5: /*a=5关闭文件*/printf("输入文件路径名");scanf("%s",name);close_file(name); /*关闭文件*/break;case 6: /*a=6删除文件*/printf("输入文件路径名");scanf("%s",name);delete(name); /*删除文件*/break;case 7: /*a=7建立目录*/printf("输入目录路径名");scanf("%s",name);md(name); /*建立目录*/break;case 8: /*a=8显示目录*/printf("输入目录路径名");scanf("%s",name);dir(name); /*显示目录*/break;case 9: /*a=9显示文件*/printf("输入文件路径名");scanf("%s",name);typefile(name); /*显示文件*/break;case 10:/* a=10改变文件属性*/printf("输入文件路径名和文件属性(1-只读文件,3-只读系统文件,4-普通文件):");scanf("%s%d",name,&attribute);change(name,attribute);}/* switch */}/* while */}/*main( )结束*/。
实习四:文件系统实习一 . 目的要求1、用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。
从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
2、要求设计一个 n个用户的文件系统,每次用户可保存m个文件,用户在一次运行中只能打开一个文件,对文件必须设置保护措施,且至少有Create、delete、open、close、read、write等命令。
二 . 例题:1、设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。
2、程序采用二级文件目录(即设置主目录[MFD])和用户文件目录(UED)。
另外,为打开文件设置了运行文件目录(AFD)。
3、为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。
4、算法与框图:①因系统小,文件目录的检索使用了简单的线性搜索。
②文件保护简单使用了三位保护码:允许读写执行、对应位为 1,对应位为0,则表示不允许读写、执行。
③程序中使用的主要设计结构如下:主文件目录和用户文件目录( MFD、UFD)打开文件目录( AFD)(即运行文件目录)文件系统算法的流程图如下:实习总结:通过这次实习,更清楚的理解了文件系统的操作,同时也对C语言编程进行了巩固。
实习代码:#include "string.h"#include "stdio.h"#include "conio.h"#include "stdlib.h"#define L 6 /* 用户最多保存的文件数 */#define N 5 /* 系统可同时管理的用户数*/int U;typedef int SX;/*文件属性 1为只读,2为写,3为可读可写*/typedef int ZT;/*文件状态 1为建立,2为打开,3为关闭*/typedef int FLAG;/*是否空表目,0为空,1为非空*/static intmemo[128]={10,20,30,40,50,60,70,80,90,100,110,120,130,140,150};/*用户文件目录*/struct FCB{char filename[20];/*文件名*/SX access;/*文件属性*/int length;/*记录长度*/int address[5];/*文件地址*/FLAG flag;/*是否空表目,0为空*/};/*用户已打开文件表*/struct UOF1{char filename[20];/*文件名*/SX access;/*文件属性*/int length;/*记录长度*/ZT flag1;/*状态*/int write;/*写指针*/int read;/*读指针*/FLAG flag;int address[5];/*文件地址*/};struct FCB UFD[N][L]={{{"abc",2,3,{10,20,30},1},{"def",1,3,{40,50,60},1},{"wj",3,3,{70,80 ,90},1}},{{"xyz",1,1,{100},1},{"aaa",2,1,{110},1}},{{"yyx",1,1,{100},1},{"ccb",1,1,{120},1}},{{"ddd",1,3,{40,50,60},1}}};struct UOF1UOF[N][L]={{"abc",2,3,2,0,0,1,{10,20,30}},{"ccb",1,1,2,0,0,1,{120}}}; struct MFD1{char username[10];int count;int opencont;struct FCB *userfaddr;struct UOF1 *openfaddr;};struct MFD1MFD[N]={"A",3,0,UFD[0],UOF[0],"B",2,0,UFD[1],UOF[1],"C",2,0,UFD[2],UO F[2],"D",1,0,UFD[3],UOF[3]};/*在UFD中找空白表项*/selectUFD(){ int i;struct FCB *P=MFD[U].userfaddr;for(i=0;i<L;i++)if(P[i].flag==0) break;if(i<L) return i;else printf("没有空登记项,文件已满!\n");}/*在UOF中找空白表项*/selectUOF(){ int j;struct UOF1 *P=MFD[U].openfaddr;for(j=0;j<L;j++)if(P[j].flag==0) break;if(j<L) return j;else printf("没有空登记项,用户已打开文件列表已满!\n");}/*建立文件函数*/void creat(/*char filename[],int L,SX access*/){struct FCB *P=MFD[U].userfaddr;int I,J;int j,le,address;char s[20];char ac;printf("请输入文件名\n");scanf("%s",s);for(j=0;j<L;j++)if(strcmp(P[j].filename,s)==0){printf("有同名文件,不能创建!\n");break;}if(j==L){printf("文件长度:\n");scanf("%d",&le); getchar();printf("文件属性:\n");scanf("%d",&ac); getchar();I=selectUFD();J=selectUOF();/*找空登记项,*/strcpy(UFD[U][I].filename,s);UFD[U][I].length=le;UFD[U][I].access=ac;UFD[U][I].flag=1;strcpy(UOF[U][J].filename,s);UOF[U][J].length=le;UOF[U][J].access=ac;UOF[U][J].flag=1;printf("请输入第一个地址\n");scanf("%d",&address);for(j=0;j<128;j++){if(memo[j]==0){memo[j]=address;break;}}UFD[U][I].address[0]=address;UOF[U][J].flag1=1;UOF[U][J].write=address;MFD[U].count++;MFD[U].opencont++;printf("\n文件创建成功!\n");}} /*以上已调试完成!20101115*//*关闭文件函数*/void close(){ int i;char name[20];char noname[20]="00000000";printf("请输入文件名:\n");scanf("%s",name);for(i=0;i<L;i++)if(strcmp(UOF[i]->filename,name)==0)if(UOF[i]->flag1==1){UOF[i]->flag1=3;}else if(UOF[i]->flag1==2){strcpy(noname,UOF[i]->filename); UOF[i]->access=0;UOF[i]->length=0;UOF[i]->write=0;UOF[i]->flag=0;printf("文件成功关闭\n");break;}else printf("文件已经关闭!\n") ;}/*CLOSE 已经调试完成!*//*打开文件函数*/void open(){char na[20];int c;int x,m,j,i;printf("请输入要打开的文件名 \n");getchar(); gets(na) ;printf("你想对文件进行写还是读操作?\n");scanf("%d",&c); getchar();for(i=0;i<L;i++){if(strcmp(UFD[U][i].filename,na)==0){m=i;for(j=0;j<5;j++){if(strcmp(UOF[U][j].filename,na)==0){if(UOF[U][j].flag1==1){printf("文件正在被创建,不能打开!\n");break;}else{printf("文件已经打开\n");break;}}}if(j==5) /*UOF中没有该文件,即:该文件尚未打开*/ {if(UFD[U][m].access==c){for(x=0;x<5;x++)if(UOF[U][x].flag==0){strcpy(UOF[U][x].filename,UFD[U][m].filename);UOF[U][x].length=UFD[U][m].length;UOF[U][x].access=UFD[U][m].access;UOF[U][x].flag1=2;UOF[U][x].flag=1;UOF[U][x].read=UFD[U][m].address[0]; UOF[U][x].write=UFD[U][m].address[0]; printf("文件打开成功\n"); break;}}else printf("操作不合法,不能打开!\n"); break; }}if(i==L)printf("文件不存在,不能打开!\n");}}/*OPEN()已调试完!*//*写文件函数*/void write(){char nam[20];int i,j,n,b,e,k;int m=-1;static int ad[5];printf("请输入要进行写操作的文件名 \n");getchar();gets(nam);for(i=0;i<5;i++){if(strcmp(UOF[U][i].filename,nam)==0){if(UOF[U][i].flag1==1)/*文件为建立状态*/{m=i;for(e=1;e<UOF[U][m].length;e++){printf("输入地址%d\n",e);scanf("%d",&ad[e]);for(k=0;k<20;k++)if(ad[e]==memo[k]){printf("the address%d is wrong and input another one\n",e);scanf("%d",&ad[e]); break;}for(j=0;j<128;j++){if(memo[j]==0){memo[j]=ad[e];break;}}UOF[U][m].address[e]=ad[e];UOF[m]->write=ad[e];}printf("写文件成功!\n");break;}else /*不是建立状态*/if(UOF[U][i].access==1){printf("操作不合法,不能写!\n");break;}else{printf("是顺序修改吗?1为顺序,0为非顺序 1/0?\n");scanf("%d",&n);if(n==1){for(e=0;e<UOF[U][m].length;e++){UOF[U][m].write=UOF[U][m].address[e] ;printf("本记录%d修改完成!,UOF[m].address[e]\n");}printf("写文件成功!\n");break;}else{printf("想修改哪条记录?\n");scanf("%d",&b);printf("the %d record is %d",b,UOF[U][m].address[b]);UOF[U][m].write=UOF[U][m].address[b] ;printf("本记录%d修改完成!,UOF[m].address[e]\n");printf("写文件成功!\n");break;}}}}if(i==5) printf("文件尚未建立或打开,不能写! \n"); }void read(){char nam[20];int i,le,m=-1;static int ad[5];int ipaddress;printf("请输入要进行读操作的文件名 \n");getchar();gets(nam);printf("请输入读长度\n");scanf("%d",&le);for(i=0;i<5;i++)/*检查文件是否已经打开*/if(strcmp(UOF[U][i].filename,nam)==0)m=i;if(i==5) printf("文件尚未打开,不能读!\n");else{ipaddress=UOF[U][m].read;for(i=0;i<le;i++)printf("%d",ipaddress++);UOF[U][m].read=ipaddress;printf("读文件成功!\n");}}delet(){ char noname[20]="00";struct FCB *P=MFD[U].userfaddr;int I;int j,i;char s[20];printf("请输入文件名\n");scanf("%s",s);for(j=0;j<L;j++)if(strcmp(P[j].filename,s)==0){printf("有该文件!\n");I=j;for(i=0;i<20;i++)/*检查文件是否已经打开*/ if(strcmp(UOF[i]->filename,s)==0){strcpy(noname,UOF[i]->filename);UOF[i]->access=0;UOF[i]->length =0;UOF[i]->write =0;UOF[i]->flag=0;}strcpy(noname,UFD[I]->filename);UFD[I]->access=0;UFD[I]->length=0;UFD[I]->address[0]=0;UFD[I]->flag=0;}printf("文件不存在,或文件已经撤销!\n");}/*显示函数*/void print_UFD(){int i ;printf("num filename access length flag ad1 ad2 ad3 ad4 ad5 \n ");for(i=0;i<5;i++)printf("\n%d\t%s\t%3d\t%3d\t%3d\t%3d\t%3d\t%3d\t%3d\t%3d\n",i,UFD [U][i].filename,UFD[U][i].access,UFD[U][i].length,UFD[U][i].flag,UFD[ U][i].address[0],UFD[U][i].address[1],UFD[U][i].address[2],UFD[U][i]. address[3],UFD[U][i].address[4]);}void print_UOF(){int i;printf("num filename access length flag write read flag1 \n ");for(i=0;i<5;i++)printf("\n%1d\t%s\t%d\t%d\t%d\t%d\t%d\t%dn",i,UOF[U][i].filename,UOF[ U][i].access,UOF[U][i].length,UOF[U][i].flag,UOF[U][i].write,UOF[U][i ].read,UOF[U][i].flag);}void main(){char name[20];int i,a;printf("欢迎使用文件管理系统 .\n");printf("\n请输入用户名\n") ;LL:scanf("%s",name); getchar();for(i=0;i<N;i++){if(strcmp(MFD[i].username,name)==0){U=i;while(1){printf("\n***************欢迎***************\n");printf("1:——————建立文件操作——————.\n");printf("2:——————打开文件操作——————.\n");printf("3:——————关闭文件操作——————.\n") ;printf("4:——————读文件操作——————.\n");printf("5:——————写文件操作——————。
操作系统课程设计题目文件系统学院计算机学院专业计算机科学与技术年级班别 10级7 班学号 3110006154 学生姓名指导教师刘老师20年月日文件系统一、课程设计的内容:模拟文件系统实现的基本功能,了解文件系统的基本结构和管理方法,加深理解文件系统的内部功能及内部实现。
通过用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有比较深入的了解。
二、可行性分析:可行性分析是通过对项目的主要内容和配套条件,并通过对各方面进行调查研究和分析比较,并对项目建成以后所带来的影响,从而提出该项目是否值得投资和如何进行建设的咨询意见,是一种综合性的系统分析方法。
可行性分析应具有预见性、公正性、可靠性、科学性的特点。
这里以三个方面来分析此次设计:经济可行性、技术可行性、法律可行性。
1、经济可行性:编写该文件系统,只需要用到PC机和VC++6.0编程软件,不需要花费金钱,所以,在经济方面,这个课程设计适合做。
2、技术可行性:在做这个课程设计,事先需要掌握的知识有C/C++语言,数据结构,操作系统,PC机的基本操作和VC++6.0软件的使用方法等。
目前,这些知识都已经学习并掌握了,所以在技术方面,这个课程设计也适合做。
3、法律可行性:做这个课程设计,只是为了掌握文件系统的基本内容,提升自己的编程能力,没有违反法律法规,所以,在法律方面,这个课程设计也适合做。
三、需求分析1.设计一个多用户多级目录文件管理系统。
2.要设计多个实用命令并设置文件保护措施。
3.设计一个较实用的用户界面,方便用户使用,界面要为用户提供足够的选择信息,不需用户打入冗长的命令4. 功能简介:①多用户管理,多级目录形式。
②基本的文件操作功能,如新建文件、打开文件、写入文件、关闭文件、读取文件等。
③用户间文件的共享功能四、概要设计(逻辑图)1.系统结构图:2、界面简单说明该系统主要分为两个界面,用户操作界面及文件操作管理界面。
#include <stdio.h>#include <malloc.h>#include <string.h>#include <time.h>#define BLOCKSIZE 1024#define SIZE 1024000#define END 65535#define FREE 0#define ROOTBLOCKNUM 2#define MAXOPENFILE 10typedef struct FCB//unsigned{char filename[8];char exname[3];unsigned char attribute;char reserve[10];//me:保留区(图3-2 MS-DOS的文件控制块)unsigned short time;unsigned short data;unsigned short first;unsigned long length;}fcb;typedef struct FAT{unsigned short id;}fat;typedef struct USEROPEN{fcb openfile[MAXOPENFILE];char dir[MAXOPENFILE][80];//me:用来记录每个打开文件所在的目录名,以方便用户打开不同目录下具有相同文件名的不同文件。
//me:即,相应打开文件所在的目录名,这样方便快速检查出指定文件是否已经打开int count;}useropen;typedef struct BLOCK0 /*引导块内容*/{char information[200];//赋值50时本身已经越界unsigned char *startblock;//me:虚拟磁盘上数据区开始位置}block0;unsigned char *myvhard;useropen *openfilelist;char currentdir[80];//me: 记录当前目录的目录名(包括目录的路径)unsigned char* startp;//me:记录虚拟磁盘上数据区开始位置void initsys();void format();void startsys();void exitsys();void create();int open(char *filename);void close(int fd);void mywrite(int fd,char *buff);void myread(int fd,char *buff);void deletefile(char *filename);void ls();void listopenfile();void cd(char *dirname);//系统初始化:创建虚盘和格式化虚盘void initsys(){myvhard=(unsigned char *)malloc(SIZE);memset(myvhard,0,SIZE);format();}void format(){FILE *fp;time_t *now;struct tm *nowtime;unsigned char *p;fat *fat1,*fat2;fcb *root;int i,a;block0 *b0;now=(time_t *)malloc(sizeof(time_t));p=myvhard;b0=(block0 *)p;strcpy(b0->information,"My filesystem,version0.01,blocksize is 1K,whole size is 1000K,emulate FAT16,Max open file number is 10");//printf("\n %s",b0->information);p+=BLOCKSIZE;//me:将虚拟磁盘的第一块分配给了引导块//me:给两个FAT各分配两个盘块fat1=(fat *)(p);fat2=(fat *)(p+BLOCKSIZE*2);//me:对于每个FAT中,前面5个块设置为已分配,后面995个块设置为空闲;//me:即,将两个fat表的前5个表项的id赋值END,第6项为的id赋值6(指向虚拟磁盘的第6块(即根目录文件所在块))fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;fat1->id=6;fat2->id=6;fat1++;fat2++;fat1->id=END;fat2->id=END;fat1++;fat2++;//me:从第7个表项开始,初始化全部是空闲的for(i=7;i<SIZE/BLOCKSIZE;i++){(*fat1).id=FREE;(*fat2).id=FREE;fat1++;fat2++;}//me:数据区第1块(即虚拟磁盘的第6块)分配给根目录文件//me:并创建两个特殊的目录项:"."和"..",其内容除了文件名不同之外,其他字段完全相同。
操作系统源代码Company Document number:WUUT-WUUY-WBBGB-BWYTT-1982GT#include<>#include<>#include<>int memoryStartAddress = -1;int memorySize = -1;struct jobList{int id; /* 作业ID */int size; /* 作业大小(需要的存储空间大小) */int status;/* 作业状态 0 : new job ,1 : in the memory , 2 : finished . */struct jobList *next; /* 作业链表指针 */};struct freeList{int startAddress; /* 分区起始地址 */int size; /* 分区大小 */struct freeList *next; /* 分区链表指针 */};struct usedList{int startAddress; /* 分区起始地址 */int jobID; /* 分区中存放作业ID */struct usedList *next; /* 分区链表指针 */};void errorMessage(void) /*出现严重错误时显示信息并结束程序*/ {printf("\n\tError !\a");printf("\nPress any key to exit !");getch();exit(1);}void openFile(FILE **fp,char *filename,char *mode)/*以要求的方式打开文件*/{if((*fp = fopen(filename,mode)) == NULL){printf("\nCan't open %s in mode %s.",filename,mode);errorMessage();}}void makeFreeNode(struct freeList **empty,int startAddress,int size)/*根据参数startAddress、size创建空闲节点,由empty指针返回*/ {if((*empty = malloc(sizeof(struct freeList))) == NULL){printf("\nNot enough to allocate for the free node .");errorMessage();}(*empty)->startAddress = startAddress;(*empty)->size = size;(*empty)->next = NULL;}void iniMemory(void) /*初始化存储空间起始地址、大小*/{char MSA[10],MS[10];printf("\nPlease input the start address of the memory !");scanf("%s",MSA);memoryStartAddress = atoi(MSA);printf("\nPlease input the size of the memory !");scanf("%s",MS);memorySize = atoi(MS);}char selectFitMethod(void) /*选择适应算法*/{FILE *fp;char fitMethod;do{printf("\n\nPlease input a char as fallow to select the fit method !\ \n 1 (Best fit) \\n 2 (Worst fit) \\n 3 (First fit) \\n 4 (Last fit)\n");fitMethod = getche();}while(fitMethod < '1' || fitMethod > '4');openFile(&fp,"d:\\","a");switch(fitMethod){case '1':fprintf(fp,"\n\n\n\n\tBest fit");fprintf(fp,"\n**********************************************");break;case '2':fprintf(fp,"\n\n\n\n\tWorst fit");fprintf(fp,"\n**********************************************");break;case '3':fprintf(fp,"\n\n\n\n\tFirst fit");fprintf(fp,"\n**********************************************");break;case '4': fprintf(fp,"\n\n\n\n\tLast fit");fprintf(fp,"\n**********************************************");break;}fclose(fp);return fitMethod;}void inputJob(void) /*从键盘输入作业到D盘的JOB文件*/{int /*id,size, */status = 0,jobnum = 0;FILE *fp;char id[10],size[10];openFile(&fp,"d:\\","w");fprintf(fp,"job_ID\tsize\tstatus");printf("\n\n\n\nPlease input the jobs as fallow !\\nEnter a integer smaller than 1 to quit .\njob_ID\tsize\n");do{/* scanf("%d%d",&id,&size); */scanf("%s\t%s",id,size);if(atoi(id) > 0 && atoi(size) > 0){fprintf(fp,"\n%s\t%s\t%d",id,size,status);/* fprintf(fp,"\n%d\t%d\t%d",id,size,status); */jobnum++;}else break;}while(1);if(jobnum)printf("\nFinished to input the jobs !");else{printf("\nNo job was given .");errorMessage();}fclose(fp);}int makeJobList(struct jobList **jobs)/*从JOB文件中读出作业并创建作业链表*/ {char jobID[10],size[10],status[10];struct jobList *rear;FILE *fp;openFile(&fp,"d:\\","r");fscanf(fp,"%s%s%s",jobID,size,status);if((*jobs = malloc(sizeof(struct jobList))) == NULL){printf("\nNot enough to allocate for the job .");fclose(fp);errorMessage();}rear = *jobs;(*jobs)->next = NULL;while(!feof(fp)){struct jobList *p;fscanf(fp,"%s%s%s",jobID,size,status);if((p = malloc(sizeof(struct jobList))) == NULL){printf("\nNot enough to allocate for the job .");fclose(fp);errorMessage();}p -> next = rear -> next;rear -> next = p;rear = rear -> next;rear -> id = atoi(jobID);rear -> size = atoi(size);rear -> status = atoi(status);}fclose(fp);return 0;}int updateJobFile(struct jobList *jobs) /*更新作业链表中作业的状态*/{FILE *fp;struct jobList *p;openFile(&fp,"d:\\","w");fprintf(fp,"job_ID\tsize\tstatus");for(p = jobs -> next;p;p = p -> next)fprintf(fp,"\n%d\t%d\t%d",p->id,p->size,p->status);fclose(fp);return 0;}int showFreeList(struct freeList *empty) /*空闲分区队列显示*/{FILE *fp;struct freeList *p = empty -> next;int count = 0;openFile(&fp,"d:\\","a");fprintf(fp,"\n\nNow show the free list...");printf("\n\nNow show the free list...");if(p){fprintf(fp,"\nnumber\tsize\tstartAddress");printf("\nnumber\tsize\tstartAddress");for(;p;p = p -> next){fprintf(fp,"\n%d\t%d\t%d",++count,p -> size,p -> startAddress);printf("\n%d\t%d\t%d",count,p -> size,p -> startAddress);}fclose(fp);return 1;}else{fprintf(fp,"\nThe memory was used out !");printf("\nThe memory was used out !");fclose(fp);return 0;}}void getJobInfo(struct jobList *jobs,int id,int *size,int *status) /*获取作业的信息*/{struct jobList *p = jobs->next;while(p && p->id != id)p = p->next;if(p == NULL){printf("\nCan't find the job which id is : %d .",id);errorMessage();}else{*size = p -> size;*status = p -> status;}}void updateJobStatus(struct jobList **jobs,int id,int status) {struct jobList *p = (*jobs)->next;while(p && p->id != id)p = p->next;if(p == NULL){printf("\nCan't find the job which id is : %d .",id);errorMessage();}elsep -> status = status;}int showUsedList(struct jobList *jobs,struct usedList *used) /*作业占用链表显示*/{FILE *fp;struct usedList *p = used -> next;int count = 0,size,status;openFile(&fp,"d:\\","a");fprintf(fp,"\n\nNow show the used list...");printf("\n\nNow show the used list...");if(p){fprintf(fp,"\nnumber\tjobID\tsize\tstartAddress");printf("\nnumber\tjobID\tsize\tstartAddress");for(;p;p = p -> next){getJobInfo(jobs,p -> jobID,&size,&status);fprintf(fp,"\n%d\t%d\t%d\t%d",++count,p->jobID,size,p-> startAddress);printf("\n%d\t%d\t%d\t%d",count,p->jobID,size,p-> startAddress);}fclose(fp);return 1;}else{fprintf(fp,"\nNo job in the memory ! You should input some jobs to it.");printf("\nNo job in the memory ! You should input some jobs to it.");fclose(fp);return 0;}}int showJobList(struct jobList *jobs) /*显示作业链表*/{struct jobList *p;p = jobs->next;if(p == NULL){printf("\nNo job in the list ! Try again next time.");return 0;}printf("\n\nThe job list is as fallow :\njob_ID\tsize\tstatus");while(p){printf("\n%d\t%d\t%d",p->id,p->size,p->status);p = p->next;}return 1;}void moveFragment(struct jobList *jobs,struct freeList **empty,struct usedList**used){int size,status;struct usedList *p;int address = memoryStartAddress;/*全局变量,初始化时分配存储空间始址*/if((*empty)->next == NULL) /* 空闲分区链表为空,提示并返回 */{printf("\nThe memory was used out at all.\nMay be you should finish some jobs first or press any key to try again !");getch();return;}for(p = (*used) -> next;p;p = p-> next)/* 循环的修改占用分区的始址 */{p -> startAddress = address;getJobInfo(jobs,p -> jobID,&size,&status);/* 由作业ID获得作业大小 */address += size;}(*empty)->next->startAddress = address;/*修改空闲分区的首节点始址、大小*/(*empty) -> next -> size = memorySize - (address - memoryStartAddress);(*empty) -> next -> next = NULL;/* 删除首节点后的所有节点 */}void order(struct freeList **empty,int bySize,int inc){struct freeList *p,*q,*temp;int startAddress,size;for(p = (*empty) -> next;p;p = p -> next){ /* 按bySize和inc两个参数寻找合适的节点,用temp指向它 */ for(temp = q = p;q;q = q -> next){switch(bySize){case 0 : switch(inc){case 0:if(q->size < temp->size)temp = q;break;default:if(q->size > temp->size)temp = q;break;} break;default: switch(inc){case 0:if(q->startAddress < temp->startAddress)temp = q;break;default:if(q->startAddress > temp->startAddress)temp = q;break;} break;}} /* 交换节点的成员值 */if(temp != p){startAddress = p->startAddress;size = p->size;p->startAddress = temp->startAddress;p->size = temp->size;temp->startAddress = startAddress;temp->size = size;}}}int allocate(struct freeList **empty,int size)/*为作业分配存储空间、状态必须为0*/{struct freeList *p,*prep;int startAddress = -1;p = (*empty) -> next;while(p && p->size < size)p = p -> next;if(p != NULL){if(p -> size > size){startAddress = p -> startAddress;p -> startAddress += size;p -> size -= size;}else{startAddress = p -> startAddress;prep = *empty;while(prep -> next != p)prep = prep -> next;prep -> next = p -> next;free(p);}}else printf("\nMay be you should move the fragment together ."); /* Unsuccessful ! */return startAddress;}void insertUsedNode(struct usedList **used,int id,int startAddress) /*插入释放的空间到used链表中(作业号为id,startAddress由函数13返回)*/{struct usedList *q,*r,*prer;if((q = malloc(sizeof(struct usedList))) == NULL){printf("\nNot enough to allocate for the used node .");errorMessage();}q -> startAddress = startAddress;q -> jobID = id;prer = *used;r = (*used) -> next;while(r && r->startAddress < startAddress){prer = r;r = r -> next;}q -> next = prer -> next;prer -> next = q;}int finishJob(struct usedList **used,int id,int *startAddress)/*结束一个作业号为id的作业,释放存储空间(由*startAddress返回空间的起始地址)*/{struct usedList *p,*prep;prep = *used;p = prep -> next;while(p && p -> jobID != id){prep = p;p = p -> next;}if(p == NULL){printf("\nThe job which id is : %d is not in the memory !",id);return 0;}else{*startAddress = p->startAddress;prep -> next = p -> next;free(p);return 1;}}void insertFreeNode(struct freeList **empty,int startAddress,int size)/*插入回收的空节点分区,处理回收分区与空闲分区的四种邻接关系。
目录1 课程设计简介 (1)1.1 课程设计的目的 (1)1.2 课程设计内容 (1)2 数据结构的设计 (2)2.1 预定义 (2)2.2 结构体 (2)2.3 全局变量和函数 (2)3 功能模块(或算法)描述 (5)3.1 模块划分 (4)3.2 模块流程图 (6)4 程序运行结果 (8)5心得体会 (9)参考文献 (10)附源代码 (11)1 课程设计简介1.1 课程设计的目的课程设计目的使学生熟悉文件管理系统的设计方法;加深对所学各种文件操作的了解及其操作方法的特点。
通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。
同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。
1.2 课程设计内容课程设计内容设计一个简单的多用户文件系统。
即①在系统中用一个文件来模拟一个磁盘;②此系统至少有:Create、delete、open、close、read、write等和部分文件属性的功能。
③实现这个文件系统。
④能实际演示这个文件系统。
基本上是进入一个界面(此界面就是该文件系统的界面)后,可以实现设计的操作要求。
1)设计一个10个用户的文件系统,每次用户可保存10个文件,一次运行用户可以打开5个文件。
2)程序采用二级文件目录(即设置主目录MFD)和用户文件目录(UFD)。
另外,为打开文件设置了运行文件目录(AFD)。
3)为了便于实现,对文件的读写作了简化,在执行读写命令时,只需改读写指针,并不进行实际的读写操作。
4)因系统小,文件目录的检索使用了简单的线性搜索。
5)文件保护简单使用了三位保护码:允许读写执行、对应位为1,对应位为0,则表示不允许读写、执行。
6)程序中使用的主要设计结构如下:主文件目录和用户文件目录(MFD、UFD),打开文件目录(AFD)即运行文件目录,如图5.1所示。
2 数据结构的设计2.1 预定义#define BLOCKSIZ 512 //磁盘块的大小#define DA TABLKNUM 512 //数据块的数目#define BLKGRUPNUM 50 //数据块组包含多少数据块#define P_N_BLOCKS 15 //inode节点中指向数据块的指针个数#define GROUPNUM DATABLKNUM/BLKGRUPNUM+1 //数据块组组数#define DINODESIZ 512 //磁盘i结点区的大小(空间32×512)#define DINODENUM 32 //磁盘i结点区的块数#define SYSOPENFILE 40#define DIRNUM 32 //一个目录下的最多目录和文件的总和数#define DIRSIZ 14 //文件、目录名的长度(字节)#define UPWDSIZ 15 //密码的长度#define UNAMSIZ 15 //用户名的长度#define PWDSIZ sizeof(struct pwd) //密码结构的长度#define PWDNUM BLOCKSIZ/PWDSIZ //密码数据空间的大小(pwd为单位)#define NOFILE 20 //一个用户最多可以打开的文件数目#define DINODESTART 4*BLOCKSIZ//i结点区的开始地址-inodes table ,1引导2超块3block bitmap 4inode bitmap#define DA TASTART (2+DINODENUM)*BLOCKSIZ //数据区的开始地址#define DATASTARTNO 36 //数据区开始指针#define DIMODE_EMPTY 00000/*可以用的空间*/#define DIMODE_FILE 00001#define DIMODE_DIR 00002#define DIMODE_PASSWD 00004#define GRUP_0 0 //管理员组#define GRUP_1 1#define GRUP_2 2#define GRUP_4 42.2 结构体//磁盘i结点结构,struct inode{// char di_name[DIRSIZ];unsigned __int16 di_ino; /*磁盘i节点标识*/unsigned __int16 di_number; /*关联文件数,当为0时表示删除文件*/unsigned __int16 di_mode; /*存取权限*/unsigned __int16 di_uid; /*磁盘i节点用户id*/unsigned __int16 di_gid; /*磁盘i节点权限组id*/ //1管理员组2用户组unsigned __int32 di_size; /*文件大小*/unsigned __int32 di_ctime; /* Creation time */unsigned __int32 di_mtime; /* Modification time */unsigned __int16 di_block[P_N_BLOCKS]; /* 一组block 指针*/};// 目录项结构struct direct{char d_name[DIRSIZ]; /*目录名(14字节)*/__int16 d_ino; /*目录号*/};//超级快结构struct super_block{unsigned __int16 s_inodes_count; /* inodes 计数*/unsigned __int16 s_blocks_count; /* blocks 计数*/unsigned __int16 s_r_blocks_count; /* 保留的blocks 计数*/unsigned __int16 s_free_blocks_count; // 空闲的blocks 计数unsigned __int16 s_free_inodes_count; /* 空闲的inodes 计数*/unsigned __int16 s_free_blocks_group[GROUPNUM];//新增一个数组来记录每个数据块组中的空闲数据块计数unsigned __int16 s_first_data_block; /* 第一个数据block */unsigned __int16 s_log_block_size; /* block 的大小*/unsigned __int16 s_blocks_per_group; /* 每block group 的block 数量*/unsigned __int16 s_inodes_per_group; /* 每block group 的inode 数量*/};// 用户密码struct pwd{unsigned __int8 p_uid;unsigned __int8 p_gid;char username[UNAMSIZ];/*用户名新加的*/char password[UPWDSIZ];};// 目录结构struct dir{struct direct direct[DIRNUM];__int16 size;};2.3 全局变量和函数// 全局变量unsigned __int8 di_bitmap[DINODENUM]; // 硬盘inode节点位图1表示已使用0表示未使用unsigned __int8 bk_bitmap[DA TABLKNUM]; // 数据块block位图struct super_block filsys; //超级块struct pwd pwd[PWDNUM];FILE *fd; //文件指针struct inode *cur_inode; //i节点当前目录指针struct inode *inodetemp; //i节点指针const char fsystemname[20]="Linux.EXT2"; //模拟硬盘的文件名struct direct dir_buf[BLOCKSIZ / sizeof(struct direct)]; //目录数组char cmdhead[20];//cmd 的头表示所在哪个文件夹、int i_lock=0;//inode位图锁可能会多线程int b_lock=0;//block位图锁struct pwd *cur_user;/* 全局函数*/extern int Format();//格式化磁盘extern int Install();//启动,安装文件系统struct inode * read_inode(int);//install里面读取文件dinodestruct direct * read_dir_data(int);//读取存储文件夹的物理块extern void showdir();//命令dirint Enterdir(char[]);//进入某个文件夹命令-- cd 文件名int Fd_dirfile(char[]);//查找当前目录里的文件没找到返回-1 找到返回inode号int Iscmd(char[]);//判断是否两个字符串的命令void two_cmd(char[],char[]);//两个字符串的命令int creat(char[]);//创建文件void changeinode();//交换指针char * ReadFile(char[]);//读取文件int mkdir(char[]);//创建文件夹void showbitmap();//显示位图int deletefd(char[]);//删除文件int editfile(char[]);//编辑文件int rename(char[]);//重命名void showhelp();//命令帮助void login();void logout();int access();//权限判断/*磁盘i节点的分配与释放(当一个新文件被建立的时候,在给该文件分配磁盘存储区之前,应为该文件分配存放该文件说明信息的磁盘i节点,当从文件系统中删除某个文件时,应首先删除它的磁盘i节点项。
#include <iostream.h>#include <windows.h>//三种模式void filter_nobuffer(char* source,char* sink,void (*func)(char* addr));void filter_sequen(char* source,char* sink,void (*func)(char* addr));void filter_overlp(char* source,char* sink,void (*func)(char* addr));//五个不同功能的操作void f1(char* addr);void f2(char* addr);void f3(char* addr);void f4(char* addr);void f5(char* addr);#define BUFFER_SIZE 1024 //定义缓冲区的大小,这里设为1024字节char * buffer; //这里的缓冲区被定义成char型void main(){//分配缓冲区buffer = new char[BUFFER_SIZE];//用于记录执行filter函数的开始时间DWORD tick;//用于求三种模式各自的平均用时DWORD nobuffer_average_time=0;DWORD sequen_average_time=0;DWORD overlp_average_time=0;//采用无缓存模式调用filter函数10次cout<<"☆无文件高速缓存模式正在运行……"<<endl;DWORD nobuffer_start_time=GetTickCount();tick = nobuffer_start_time;filter_nobuffer("source.txt","nobuffer_1.txt",f1);cout<<"nobuffer 0-1: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_1.txt","nobuffer_2.txt",f2);cout<<"nobuffer 1-2: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_2.txt","nobuffer_3.txt",f3);cout<<"nobuffer 2-3: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_3.txt","nobuffer_4.txt",f4);cout<<"nobuffer 3-4: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_4.txt","nobuffer_5.txt",f5);tick = GetTickCount();filter_nobuffer("nobuffer_5.txt","nobuffer_6.txt",f1);cout<<"nobuffer 5-6: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_6.txt","nobuffer_7.txt",f2);cout<<"nobuffer 6-7: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_7.txt","nobuffer_8.txt",f3);cout<<"nobuffer 7-8: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_8.txt","nobuffer_9.txt",f4);cout<<"nobuffer 8-9: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_nobuffer("nobuffer_9.txt","nobuffer_10.txt",f5);DWORD nobuffer_end_time=GetTickCount();cout<<"nobuffer 9-10: "<<nobuffer_end_time - tick<<" ms."<<endl<<endl; //采用高速缓存模式调用filter函数10次cout<<"★使用文件高速缓存模式正在运行……"<<endl;DWORD sequen_start_time=GetTickCount();tick = sequen_start_time;filter_sequen("source.txt","sequen_1.txt",f1);cout<<"sequen 0-1: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_1.txt","sequen_2.txt",f2);cout<<"sequen 1-2: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_2.txt","sequen_3.txt",f3);cout<<"sequen 2-3: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_3.txt","sequen_4.txt",f4);cout<<"sequen 3-4: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_4.txt","sequen_5.txt",f5);cout<<"sequen 4-5: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_5.txt","sequen_6.txt",f1);cout<<"sequen 5-6: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_6.txt","sequen_7.txt",f2);cout<<"sequen 6-7: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_7.txt","sequen_8.txt",f3);tick = GetTickCount();filter_sequen("sequen_8.txt","sequen_9.txt",f4);cout<<"sequen 8-9: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_sequen("sequen_9.txt","sequen_10.txt",f5);DWORD sequen_end_time=GetTickCount();cout<<"sequen 9-10: "<<sequen_end_time - tick<<" ms."<<endl<<endl; //采用异步模式调用filter函数10次cout<<"◎异步传输模式正在运行……"<<endl;DWORD overlp_start_time=GetTickCount();tick = overlp_start_time;filter_overlp("source.txt","overlp_1.txt",f1);cout<<"overlp 0-1: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_1.txt","overlp_2.txt",f2);cout<<"overlp 1-2: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_2.txt","overlp_3.txt",f3);cout<<"overlp 2-3: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_3.txt","overlp_4.txt",f4);cout<<"overlp 3-4: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_4.txt","overlp_5.txt",f5);cout<<"overlp 4-5: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_5.txt","overlp_6.txt",f1);cout<<"overlp 5-6: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_6.txt","overlp_7.txt",f2);cout<<"overlp 6-7: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_7.txt","overlp_8.txt",f3);cout<<"overlp 7-8: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_8.txt","overlp_9.txt",f4);cout<<"overlp 8-9: "<<GetTickCount() - tick<<" ms."<<endl;tick = GetTickCount();filter_overlp("overlp_9.txt","overlp_10.txt",f5);DWORD overlp_end_time=GetTickCount();cout<<"overlp 9-10: "<<overlp_end_time - tick<<" ms."<<endl<<endl;//输出三种模式下的平均时间以做对比cout<<"■三种模式的平均用时如下:"<<endl;cout<<"·无文件高速缓存模式平均用时:"<<(nobuffer_end_time-nobuffer_start_time)/10<<" ms."<<endl;cout<<"·使用文件高速缓存模式平均用时:"<<(sequen_end_time-sequen_start_time)/10<<" ms."<<endl;cout<<"·异步传输模式平均用时:"<<(overlp_end_time-overlp_start_time)/10<<" ms."<<endl<<endl;return;}//对文件内容进行的5种操作(可以任意定义),本程序仅用了五个很简单的操作//f1 +1//f2 -1//f3 *1//f4 >>//f5 <<void f1(char* addr){ *addr = (unsigned char)*addr + 1; }void f2(char* addr){ *addr = (unsigned char)*addr - 1; }void f3(char* addr){ *addr = (unsigned char)*addr * 1; }void f4(char* addr){ *addr = (unsigned char)*addr >> 1;}void f5(char* addr){ *addr = (unsigned char)*addr << 1;}//没有文件高速缓存的filter函数void filter_nobuffer(char* source, char* sink, void (*func) (char* addr)){HANDLE handle_src,handle_dst; //定义源文件与目标文件的句柄BOOL cycle; //用以判断是否满一个缓冲区DWORD NumberOfBytesRead,NumberOfBytesWrite,index; //读的字节数、写的字节数//打开源文件handle_src=CreateFile(source,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG _NO_BUFFERING,NULL);//创建目标文件handle_dst = CreateFile(sink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NULL);//如果打开或创建失败,则报错if( handle_src == INVALID_HANDLE_VALUE || handle_dst == INVALID_HANDLE_VALUE){cout<<"CreateFile Invocation Error!"<<endl;exit(1);}cycle = TRUE;//用cycle判断文件什么时候读完while(cycle){//从源文件读数据送入缓冲区if(ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL) == FALSE){cout<<"ReadFile Error!"<<endl;exit(1);}//当读不满一个缓冲区时,说明达到文件末尾,结束循环if(NumberOfBytesRead < BUFFER_SIZE)cycle = FALSE;//对文件内容进行的操作for(index = 0;index < NumberOfBytesRead;index++)func(&buffer[index]);//将缓冲区中的数据写入目标文件if(WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL) == FALSE){cout<<"WriteFile Error!"<<endl;exit(1);}}//关闭文件句柄CloseHandle(handle_src);CloseHandle(handle_dst);}void filter_sequen(char* source, char* sink, void (*func) (char* addr)){HANDLE handle_src,handle_dst; //定义源文件与目标文件的句柄BOOL cycle; //用以判断是否满一个缓冲区DWORD NumberOfBytesRead,NumberOfBytesWrite,index; //读的字节数、写的字节数//CreateFile函数设置参数FILE_FLAG_SEQUENTIAL_SCAN:使用文件高速缓存//打开源文件handle_src=CreateFile(source,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG _SEQUENTIAL_SCAN,NULL);//创建目标文件handle_dst=CreateFile(sink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_FLAG _SEQUENTIAL_SCAN,NULL);//如果打开或创建失败,则报错if( handle_src == INVALID_HANDLE_VALUE || handle_dst ==INVALID_HANDLE_VALUE){cout<<"CreateFile Invocation Error!"<<endl;exit(1);}cycle = TRUE;//用cycle判断文件什么时候读完while(cycle){//从源文件读数据送入缓冲区if(ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,NULL)==FALSE) {cout<<"ReadFile Error!"<<endl;exit(1);}//当读不满一个缓冲区时,说明达到文件末尾,结束循环if(NumberOfBytesRead < BUFFER_SIZE)cycle = FALSE;//对文件内容进行的操作for(index = 0;index < NumberOfBytesRead;index++)func(&buffer[index]);//将缓冲区中的数据写入目标文件if(WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite,NULL) == FALSE){cout<<"WriteFile Error!"<<endl;exit(1);}}//关闭文件句柄CloseHandle(handle_src);CloseHandle(handle_dst);}void filter_overlp(char* source, char* sink, void (*func) (char* addr)){HANDLE handle_src,handle_dst; //定义源文件与目标文件的句柄BOOL cycle; //用以判断是否满一个缓冲区//读的字节数、写的字节数、GetLastError函数的返回值DWORD NumberOfBytesRead,NumberOfBytesWrite,index,dwError; OVERLAPPED overlapped; //overlapped 结构//打开源文件handle_src=CreateFile(source,GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,NULL);//创建目标文件handle_dst=CreateFile(sink,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,NULL,NUL L);//如果打开或创建失败,则报错if( handle_src == INVALID_HANDLE_VALUE || handle_dst == INVALID_HANDLE_VALUE){cout<<"CreateFile Invocation Error"<<endl;exit(1);}//对overlapped结构初始化overlapped.hEvent=NULL;overlapped.Offset=-BUFFER_SIZE;overlapped.OffsetHigh=0;cycle = TRUE;//用cycle判断文件什么时候读完while(cycle){//计算文件的偏移量overlapped.Offset = overlapped.Offset + BUFFER_SIZE;//读源文件if(ReadFile(handle_src,buffer,BUFFER_SIZE,&NumberOfBytesRead,&overlapped) == FALSE){switch(dwError = GetLastError()){//读到文件结尾case ERROR_HANDLE_EOF:cycle = FALSE;break;//异步传输正在进行case ERROR_IO_PENDING:if(GetOverlappedResult(handle_src,&overlapped,&NumberOfBytesRead,TRUE) == FALSE){cout<<"GetOverlappedResult Error!"<<endl;exit(1);}break;default:break;}}//当读不满一个缓冲区时,说明达到文件末尾,结束循环if(NumberOfBytesRead < BUFFER_SIZE)cycle = FALSE;//对文件内容进行的操作for(index = 0;index < NumberOfBytesRead;index++)func(&buffer[index]);//将缓冲区中的数据写入目标文件if(WriteFile(handle_dst,buffer,NumberOfBytesRead,&NumberOfBytesWrite, NULL) == FALSE){cout<<"WriteFile Error!"<<endl;exit(1);}}//关闭文件句柄CloseHandle(handle_src);CloseHandle(handle_dst);}。