操作系统试验—快速文件系统源代码

合集下载

北京邮电大学计算机学院 - 操作系统实验报告(含源代码)

北京邮电大学计算机学院 - 操作系统实验报告(含源代码)
小组成员:许伟林 08211306 (6 班) 刘惠庭 08211338 (7 班)
1/58
10 年 12 月 19 日
内容目录
实验 1.3 Shell 编程...........................................................4 1、实验目的...............................................................4 2、实验内容...............................................................4 3、实验原理...............................................................4 4、实验步骤...............................................................4 5、实验结果:.............................................................4 6、人员任务分配...........................................................5
实验项目:
1. 实验 1.3 Shell 编程 2. 实验 2.3 内核模块 3. 实验 2.4 系统调用 4. 实验 3.3 Shell 编程实验(进程管理实验) 5. 实验 4.1 观察实验(存储管理实验) 6. 实验 5.1 观察实验(进程通信) 7. 实验 6.3 Io 系统编程实验 8. 实验 6.4 设备驱动程序 9. 实验 7.1 代码分析(文件系统管理实验)
实验 3.3 Shell 编程实验(进程管理实验)......................................18 1、实验目的..............................................................18 2、实验内容..............................................................18 3、实验原理..............................................................18 4、实验步骤..............................................................18 5、实验结果及分析........................................................19 6、人员任务分配..........................................................19 2、实验内容 2............................................................20 3、实验原理..............................................................20 4、实验步骤..............................................................20 5、实验结果及分析........................................................23 6、人员分配..............................................................24

操作系统实验文件管理C++代码

操作系统实验文件管理C++代码

#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]。

操作系统实验_示例代码_linux

操作系统实验_示例代码_linux

《计算机操作系统》实验指导苏州科技学院电子与信息工程系软件教研室二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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#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);}。

相关文档
最新文档