操作系統實驗報告——文件算法
**1.實驗名稱:*文件操作算法的實現
2.實驗要求:
(1)理解文件操作的基本思想.
(2)掌握文件的基本操作算法(創建、刪除、打開、關閉、讀、寫)
(3)用C或C++語言編程實現文件基本操作算法。
3.實驗方式: 通過上機,實際調試運行程序。
4.實驗環境:
(1)硬件環境:PC機一臺;
(2)軟件環境:Windows 10操作系統, C或C++程序設計語言。
5.實驗過程:
(1)算法描述:
文件的創建與打開。
FILE apply_room(char sys_name){
f = fopen(sys_name,“w+b”); //創建一個新的可讀寫的二進制文件
fseek(f,SYS_SIZE,SEEK_SET);
fputc(EOF, f);
fclose(f);
return fopen(sys_name,“r+b”);//打開一個可讀寫的二進制文件
}
void create():{
int i,inode_num;
long t;
char name[12];
printf(“輸入文件名:”);
scanf("%s",name);
getchar();
if(namei(name)!=-1)
printf(“文件已退出!\n”);
else{
inode_num=ialloc();
strcpy(file.name,name);
file.inode_num=inode_num;
fseek(f,BLOCK_SIZE+inode_num16,SEEK_SET);
fwrite(&file,sizeof(struct filelist),1,f);
inode.i_size=0;
inode.block_amount=0;
for(i=0;i<16;i++) inode.i_addr[i]=0;
time(&t);
strcpy(inode.create_time,ctime(&t));
fseek(f,4BLOCK_SIZE+inode_numsizeof(struct inode),SEEK_SET);
fwrite(&inode,sizeof(struct inode),1,f);
p->s_inode[inode_num]=0;
printf(“創建成功!\n”);
}
}
在文件系統中創建自己的文件
void open_file(){
int i=0,j=0,k=0;
int m,n;
char name[12];
printf(“輸入文件名:”);
scanf("%s",name);
getchar();
n=namei(name);
if(n==-1)
printf(“文件不存在!\n”);
else if(p->s_inode[n]>0)
printf(“文件已打開\n”);
else{
while(fcb[i].used1) i++;
while(table[j].f_node) j++;
while(fd[k].t_node) k++;
fd[k].t_node=&table[j];
table[j].f_node=&fcb[i];
strcpy(fcb[i].name,name);
fcb[i].inode_num=n;
fcb[i].used=1;
fseek(f,4BLOCK_SIZE+nsizeof(struct inode),SEEK_SET);
fread(&inode,sizeof(struct inode),1,f);
fcb[i].i_size=inode.i_size;
fcb[i].block_amount=inode.block_amount;
for(m=0;m<16;m++) fcb[i].i_addr[m]=inode.i_addr[m];
p->s_inode[n]=k+100;
printf(“文件已打開!\n”);
}
}
打開剛剛或之前建立的文件
文件的讀寫
void write_file() {
int k,block_amount,n,size=0,i=0;
long block_num;
char ch,name[12];
printf(“輸入文件名”);
scanf("%s",name);
getchar();
n=name_i(name);
if(n-1) printf(“文件不存在或未打開!\n”);
else{
k=p->s_inode[n]-100;
ptr=fd[k].t_node->f_node;
while(iblock_amount){
block_num=ptr->i_addr[i];
myfree(block_num);
i++;
}
block_amount=0;
printf(“輸入文件的上下文:(用“”結束)\n");
while((ch=getchar())!=’’&&block_amount<16){
size++;
if(size1){
block_num=myalloc();
inode.i_addr[block_amount]=ptr->i_addr[block_amount]=block_num;
block_amount++;
fseek(f,(block_num-1)BLOCK_SIZE,SEEK_SET);
}
fputc(ch,f);
}
getchar();
inode.i_size=ptr->i_size=size;
inode.block_amount=ptr->block_amount=block_amount;
fseek(f,4BLOCK_SIZE+n*sizeof(struct inode),SEEK_SET);
fwrite(&inode,sizeof(struct inode),1,f);
}
}
void read_file() {
int k,n,block_amount,size;
int i=0;
long block_num;
char name[12],buf[512];
printf(“輸入文件名:”);
scanf("%s",name);
getchar();
n=name_i(name);
if(n-1)
printf(“文件不存在或未打開!”);
else{
k=p->s_inode[n]-100;
ptr=fd[k].t_node->f_node;
size=ptr->i_size;
block_amount=ptr->block_amount;
for(i=0;i<block_amount;i++){
block_num=ptr->i_addr[i];
fseek(f,(block_num-1)*BLOCK_SIZE,SEEK_SET);
if(size>512) {fread(buf,sizeof(char),512,f); size=size-512;}
else{
fread(buf,sizeof(char),size,f);
buf[size]=’\0’;
}
printf(”%s",buf);
}
}
printf("\n");
}
退出文件系統
void myexit(){
int i=0;
char ch;
while(fcb[i].used0) i++;
if(i<5){
getchar();
printf(“一些文件仍處於打開狀態!!!\n”);
printf(“輸入“q”或其他鍵返回\n”);
scanf("%c",&ch);
if(ch’q’){
while(i<5){
if(fcb[i].used==1) p->s_inode[fcb[i].inode_num]=0;
i++;
}
fseek(f,0,SEEK_SET);
fwrite(p,sizeof(struct filsys),1,f);
exit(0);
}
getchar();
}
else{
fseek(f,0,SEEK_SET);
fwrite(p,sizeof(struct filsys),1,f);
exit(0);
}
} //退出此文件系統
(2)實現代碼:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#define SYS_SIZE 0XFFFFF*100
#define BLOCK_SIZE 512
FILE *f;
struct filsys{
int s_nfree;
long s_free[100];
int s_ninode;
int s_inode[96];
}*p;
struct index_block{
int s_nfree;
long s_free[96];
}q;
struct filelist{
char name[14];
int inode_num;
}file;
struct inode{
int i_size;
int block_amount;
long i_addr[16];
char create_time[25];
}inode;
struct fcb{
char name[12];
int inode_num;
int used;
int i_size;
int block_amount;
long i_addr[16];
}fcb[5],*ptr;
struct open_file_table{
int offset;
struct fcb* f_node;
}table[5];
struct fd{
struct open_file_table* t_node;
}fd[5];
FILE* apply_room(char *sys_name){
f = fopen(sys_name,"w+b"); //創建一個新的可讀寫的二進制文件
fseek(f,SYS_SIZE,SEEK_SET);
fputc(EOF, f); //打開一個可讀寫的二進制文件
}
void myfree(long block_num){
int i;
if(p->s_nfree<100){
p->s_free[p->s_nfree]=block_num;
p->s_nfree++;
}
else{
q.s_nfree=p->s_nfree;
for(i=0;i<100;i++)
q.s_free[i]=p->s_free[i];
fseek(f,(block_num-1)*BLOCK_SIZE,SEEK_SET);
fwrite(&q,sizeof(struct index_block),1,f);
p->s_nfree=1;
p->s_free[0]=block_num;
}
}
long myalloc(){
int i;
long a;
p->s_nfree--;
if(p->s_nfree==0){
a=p->s_free[0];
fseek(f,(a-1)*BLOCK_SIZE,SEEK_SET);
fread(&q,sizeof(struct index_block),1,f);
p->s_nfree=q.s_nfree;
for(i=0;i<100;i++)
p->s_free[i]=q.s_free[i];
return a;
}
else
return p->s_free[p->s_nfree];
}
void init(){
int j;
long i;
p->s_nfree=1;
p->s_free[0]=0;
p->s_ninode=96;
for(i=0;i<96;i++)
p->s_inode[i]=-1;
for(i=22;i<=SYS_SIZE/BLOCK_SIZE;i++)
myfree(i);
j=p->s_nfree+1;
while(j<100)
p->s_free[j++]=0;
fseek(f,0,SEEK_SET);
fwrite(p,sizeof(struct filsys),1,f);
}
int ialloc(){
int i=0;
while(p->s_inode[i]>=0)
i++;
p->s_inode[i]=0;
p->s_ninode--;
return i;
}
int namei(char *name){
int k=0;
while(k<96){
if(p->s_inode[k]!=-1){
fseek(f,BLOCK_SIZE+k*16,SEEK_SET);
fread(&file,sizeof(struct filelist),1,f);
if(!strcmp(file.name,name))
return file.inode_num;
}
k++;
};
return -1;
}
int name_i(char *name){
int k=0;
do{
if(fcb[k].used==1){
if(!strcmp(fcb[k].name,name))
return fcb[k].inode_num;
}
k++;
}
while(k<5);
return -1;
}
void create(){
int i,inode_num;
long t;
char name[12];
printf("輸入文件名:");
scanf("%s",name);
getchar();
if(namei(name)!=-1) printf("文件已退出!\n");
else{
inode_num=ialloc();
strcpy(file.name,name);
file.inode_num=inode_num;
fseek(f,BLOCK_SIZE+inode_num*16,SEEK_SET);
fwrite(&file,sizeof(struct filelist),1,f);
inode.i_size=0;
inode.block_amount=0;
for(i=0;i<16;i++)
inode.i_addr[i]=0;
time(&t);
strcpy(inode.create_time,ctime(&t));
fseek(f,4*BLOCK_SIZE+inode_num*sizeof(struct inode),SEEK_SET);
fwrite(&inode,sizeof(struct inode),1,f);
p->s_inode[inode_num]=0;
printf("創建成功!\n");
}
}
void open_file(){
int i=0,j=0,k=0;
int m,n;
char name[12];
printf("輸入文件名:");
scanf("%s",name);
getchar();
n=namei(name);
if(n==-1)
printf("文件不存在!\n");
else if(p->s_inode[n]>0)
printf("文件已打開\n");
else{
while(fcb[i].used==1)
i++;
while(table[j].f_node)
j++;
while(fd[k].t_node)
k++;
fd[k].t_node=&table[j];
table[j].f_node=&fcb[i];
strcpy(fcb[i].name,name);
fcb[i].inode_num=n;
fcb[i].used=1;
fseek(f,4*BLOCK_SIZE+n*sizeof(struct inode),SEEK_SET);
fread(&inode,sizeof(struct inode),1,f);
fcb[i].i_size=inode.i_size;
fcb[i].block_amount=inode.block_amount;
for(m=0;m<16;m++)
fcb[i].i_addr[m]=inode.i_addr[m];
p->s_inode[n]=k+100;
printf("文件已打開!\n");
}
}
void write_file(){
int k,block_amount,n,size=0,i=0;
long block_num;
char ch,name[12];
printf("輸入文件名");
scanf("%s",name);
getchar();
n=name_i(name);
if(n==-1)
printf("文件不存在或未打開!\n");
else{
k=p->s_inode[n]-100;
ptr=fd[k].t_node->f_node;
while(i<ptr->block_amount){
block_num=ptr->i_addr[i];
myfree(block_num);
i++;
}
block_amount=0;
printf("輸入文件的上下文:(用“*”結束)\n");
while((ch=getchar())!='*'&&block_amount<16){
size++;
if(size==1){
block_num=myalloc();
inode.i_addr[block_amount]=ptr->i_addr[block_amount]=block_num;
block_amount++;
fseek(f,(block_num-1)*BLOCK_SIZE,SEEK_SET);
}
fputc(ch,f);
}
getchar();
inode.i_size=ptr->i_size=size;
inode.block_amount=ptr->block_amount=block_amount;
fseek(f,4*BLOCK_SIZE+n*sizeof(struct inode),SEEK_SET);
fwrite(&inode,sizeof(struct inode),1,f);
}
}
void read_file(){
int k,n,block_amount,size;
int i=0;
long block_num;
char name[12],buf[512];
printf("輸入文件名:");
scanf("%s",name);
getchar();
n=name_i(name);
if(n==-1) printf("文件不存在或未打開!");
else{
k=p->s_inode[n]-100;
ptr=fd[k].t_node->f_node;
size=ptr->i_size;
block_amount=ptr->block_amount;
for(i=0;i<block_amount;i++){
block_num=ptr->i_addr[i];
fseek(f,(block_num-1)*BLOCK_SIZE,SEEK_SET);
if(size>512){
fread(buf,sizeof(char),512,f);
size=size-512;
}
else{
fread(buf,sizeof(char),size,f);
buf[size]='\0';
}
printf("%s",buf);
}
}
printf("\n");
}
void del_file(){
int n,i=0;
long block_num;
char name[12];
printf("輸入文件名:");
scanf("%s",name);
getchar();
n=namei(name);
if(n==-1)
printf("文件不存在!\n");
else if(p->s_inode[n]>0)
printf("文件已打開!請先關閉!\n");
else{
p->s_inode[n]=-1;
fseek(f,4*BLOCK_SIZE+n*sizeof(struct inode),SEEK_SET);
fread(&inode,sizeof(struct inode),1,f);
while(i<inode.block_amount){
block_num=inode.i_addr[i];
myfree(block_num);
i++;
}
strcpy(file.name,"");
file.inode_num=0;
fseek(f,BLOCK_SIZE+n*16,SEEK_SET);
fwrite(&file,sizeof(struct filelist),1,f);
printf("文件已刪除!\n");
}
}
void close_file(){
int k,n;
char name[12];
printf("輸入文件名:");
scanf("%s",name);
getchar();
n=name_i(name);
if(n==-1)
printf("文件不存在或未打開\n");
else{
k=p->s_inode[n]-100;
fd[k].t_node->f_node->used=0;
fd[k].t_node->f_node=NULL;
fd[k].t_node=NULL;
p->s_inode[n]=0;
printf("文件已關閉!\n");
}
}
void myexit(){
int i=0;
char ch;
while(fcb[i].used==0) i++;
if(i<5){
getchar();
printf("一些文件仍處於打開狀態!!!\n");
printf("輸入“q”或其他鍵返回\n");
scanf("%c",&ch);
if(ch=='q'){
while(i<5){
if(fcb[i].used==1)
p->s_inode[fcb[i].inode_num]=0;
i++;
}
fseek(f,0,SEEK_SET);
fwrite(p,sizeof(struct filsys),1,f);
exit(0);
}
getchar();
}else{
fseek(f,0,SEEK_SET);
fwrite(p,sizeof(struct filsys),1,f);
exit(0);
}
}
void main(){
int i;
char ch,sys_name[15];
p=(struct filsys *)malloc(sizeof(struct filsys));
while(1){
printf("--------------1:創建新文件系統---------------\n");
printf("--------------2:打開已有的文件系統-----------\n");
printf("請選擇:");
if((ch=getchar())=='1'){
printf("輸入文件系統名稱:");
scanf("%s",sys_name);
getchar();
f=apply_room(sys_name);
init();
break; //這裏的break用來跳出while(1)的循環
}
else if(ch=='2'){
printf("輸入文件系統名稱:");
scanf("%s",sys_name);
getchar();
f=fopen(sys_name,"r+b");
fseek(f,0,SEEK_SET);
fread(p,sizeof(struct filsys),1,f);
break;
}
else{
printf("輸入有誤!\n");
getchar();
}
};
for(i=0;i<5;i++){
fcb[i].used=0;
table[i].f_node=NULL;
fd[i].t_node=NULL;
}
while(1){
printf("-------------------------------------------------------------------------------------------------\n");
printf("|~~~~~~~~~~~~~~~~~~~~~~1:新建文件~~~~~~~~~~~~~~~~~~~~~~~~~~|\n");
printf("|~~~~~~~~~~~~~~~~~~~~~~2:打開文件~~~~~~~~~~~~~~~~~~~~~~~~~~|\n");
printf("|~~~~~~~~~~~~~~~~~~~~~~3:編輯文件~~~~~~~~~~~~~~~~~~~~~~~~~~|\n");
printf("|~~~~~~~~~~~~~~~~~~~~~~4:閱讀文件~~~~~~~~~~~~~~~~~~~~~~~~~~|\n");
printf("|~~~~~~~~~~~~~~~~~~~~~~5:關閉文件~~~~~~~~~~~~~~~~~~~~~~~~~~|\n");
printf("|~~~~~~~~~~~~~~~~~~~~~~6:刪除文件~~~~~~~~~~~~~~~~~~~~~~~~~~|\n");
printf("|~~~~~~~~~~~~~~~~~~~~~~7:退 出~~~~~~~~~~~~~~~~~~~~~~~~~~|\n");
printf("------------------------------------------------------------------------------------------------\n");
printf("請選擇:");
switch(getchar()-'0'){
case 1:
create();
break;
case 2:
open_file();
break;
case 3:
write_file();
break;
case 4:
read_file();
break;
case 5:
close_file();
break;
case 6:
del_file();
break;
case 7:
myexit();
break;
default:getchar();
printf("輸入有誤!\n"); break;
}
};
free(p);
fclose(f);
}