?? newfile.cpp
字號:
{ //否則返回-1
int parent,p=0,index;
parent=get_parent(old_name,p); //跟對目錄重命名一樣
if(parent==-1)
{
printf("Path name error!\n");
return -1;
}
int file_id=search(parent,old_name+p,1,index);
if(file_id==-1)
{
printf("The file not exist!\n");
return -1;
}
if(strcmp(old_name+p,new_name)!=0 && search(parent,new_name,1,index)!=-1)
{
printf("File name repeated!\n");
return -1;
}
strcpy(file[file_id].file_name,new_name);
al_file[file_id]++;
return file_id;
}
void del_file(int pos) //刪除文件,調(diào)用該函數(shù)的前提是已經(jīng)取得要刪除文件
{ //的索引號
return_block(pos); //釋放磁盤塊
file_flag[pos]=0;
used_file--;
al_fflag[pos]++;
al_file[pos]=0;
if(open_files[pos]>0) //如果已經(jīng)獲得緩沖區(qū),則立即釋放
{
int buf_id=get_buffer_id(pos);
buffer[buf_id].flag=0;
open_files[pos]=0;
}
}
int del_file(int parent,char *file_name) //在指定的目錄下刪除文件,刪除成功則返回文件的
{ //索引號,否則返回-1
int del_pos,index;
if((del_pos=search(parent,file_name,1,index))==-1)//搜索該文件是否存在,不存在則刪除失敗
{
printf("The file to delete not exist!\n");
return -1;
}
del_file(del_pos); //開始刪除文件
struct dir_node *p=&dir[parent]; //修改父目錄的控制信息
if(p->file_count>=2)
{
int top=p->file_count-1;
p->child_file[index]=p->child_file[top];
}
p->file_count--;
al_dir[parent]++;
return del_pos;
}
int delfile(char *name) //刪除文件的主調(diào)函數(shù)
{
int parent,p=0;
parent=get_parent(name,p);
if(parent==-1)
{
printf("Path name error!\n");
return -1;
}
return del_file(parent,name+p);
}
void del_dir(int pos) //刪除指定的目錄節(jié)點,該目錄已經(jīng)為空
{
dir_flag[pos]=0;
used_dir--;
al_dflag[pos]++;
al_dir[pos]=0;
}
void del(int pos) //刪除一個指定目錄及它下面的所有文件及所有目錄
{
for(int i=0;i<dir[pos].file_count;i++) //刪除當(dāng)前目錄下的所有文件
del_file(dir[pos].child_file[i]);
for(i=0;i<dir[pos].dir_count;i++) //刪除子目錄
del(dir[pos].child_dir[i]);
del_dir(pos); //刪除當(dāng)前目錄
}
void del_dir(int parent,int del_pos,int index) //在一個指定的目錄下刪除一個目錄及它下面的所有
{ //文件及所有目錄
del(del_pos); //開始刪除目錄
if(dir[parent].dir_count>=2) //修改父目錄的控制信息
{
int top=dir[parent].dir_count-1;
dir[parent].child_dir[index]=dir[parent].child_dir[top];
}
dir[parent].dir_count--;
al_dir[parent]++;
}
void paste(int dir_id) //用于設(shè)置當(dāng)前路徑
{
if(dir_id==0)
return;
paste(dir[dir_id].parent);
strcat(curr_path,dir[dir_id].dir_name);
strcat(curr_path,"/");
}
int change_dir(char *name) //改變工作目錄,成功則返回該目
{ //錄的索引號,否則返回-1
int parent,p=0,pos,index;
if(strcmp(name,"/")==0)
pos=0;
else if(strcmp(name,"..")==0)
pos=curr_dir->parent;
else
{
parent=get_parent(name,p);
if(parent==-1)
{
printf("Path name error!\n");
return -1;
}
pos=search(parent,name+p,0,index);
}
if(pos==-1) //如果該目錄不存在,則失敗
{
printf("The dictory not exist!\n");
return -1;
}
curr_path[3]='\0';
paste(pos);
curr=pos; //改變當(dāng)前目錄及路徑
curr_dir=&dir[curr];
return curr;
}
int count[DIR_NUM]; //用于顯示目錄樹時用
void print_sp(int dir_id) //該函數(shù)用于打印|用,可以將目錄結(jié)構(gòu)以樹形
{ //顯示
if(dir_id<0)
return;
print_sp(dir[dir_id].parent);
if(dir[dir_id].dir_count>count[dir_id])
printf("|");
else
printf(" ");
for(int i=0;i<6;i++)
printf(" ");
}
void print_pre(int id,int type) //該函數(shù)在每打印一個目錄或文件名之前調(diào)用
{
int parent,pre;
if(type==0)
parent=dir[id].parent;
else
parent=file[id].parent;
pre=dir[parent].parent;
print_sp(pre);
}
void print_file(int file_id) //打印文件名
{
print_pre(file_id,1);
printf("|");
for(int i=0;i<6;i++)
printf("_");
printf("%s\n",file[file_id].file_name);
}
void print_dir(int dir_id) //打印目錄名
{
print_pre(dir_id,0);
printf("|");
for(int i=0;i<6;i++)
printf("_");
printf("%s\057\n",dir[dir_id].dir_name);
count[dir[dir_id].parent]++;
}
void print(int dir_id) //打印樹形結(jié)構(gòu)的核心函數(shù)
{
print_dir(dir_id);
for(int i=0;i<dir[dir_id].file_count;i++)
print_file(dir[dir_id].child_file[i]);
for(i=0;i<dir[dir_id].dir_count;i++)
print(dir[dir_id].child_dir[i]);
}
void show_tree() //打印樹形結(jié)構(gòu)的主調(diào)函數(shù)
{
if(used_file==0 && used_dir==1)
{
printf("The file system is empty!\n");
return;
}
printf("%s\057\n",dir[0].dir_name);
for(int i=0;i<DIR_NUM;i++)
count[i]=0;
for(i=0;i<dir[0].file_count;i++)
print_file(dir[0].child_file[i]);
for(i=0;i<dir[0].dir_count;i++)
print(dir[0].child_dir[i]);
}
void show_dir(int dir_id) //以下幾個函數(shù)用于顯示當(dāng)前目錄下面的目錄和文件,
{ //跟上面不同的是,它不能顯示目錄及文件之間的關(guān)系,
printf("%s",dir[dir_id].dir_name); //但它可以顯示一些細(xì)節(jié),如創(chuàng)建時間,文件長度
for(int i=strlen(dir[dir_id].dir_name);i<20;i++)
printf(" ");
printf("<DIR>");
for(i=25;i<30;i++)
printf(" ");
printf("%d-%.2d-%.2d %.2d:%.2d:%.2d\n",dir[dir_id].ctime.wYear,dir[dir_id].ctime.wMonth,dir[dir_id].ctime.wDay,dir[dir_id].ctime.wHour,dir[dir_id].ctime.wMinute,dir[dir_id].ctime.wSecond);
}
void show_file(int file_id) //顯示一個文件
{
printf("%s",file[file_id].file_name);
for(int i=strlen(file[file_id].file_name);i<20;i++)
printf(" ");
printf("<FILE>");
for(i=26;i<30;i++)
printf(" ");
printf("%d-%.2d-%.2d %.2d:%.2d:%.2d",file[file_id].ctime.wYear,file[file_id].ctime.wMonth,file[file_id].ctime.wDay,file[file_id].ctime.wHour,file[file_id].ctime.wMinute,file[file_id].ctime.wSecond);
for(i=0;i<8;i++)
printf(" ");
int length=file[file_id].file_length;
if(open_files[file_id]==2) //如果該文件已經(jīng)以寫的方式被打開,則需改變
{
int buf_id=get_buffer_id(file_id);
length=buffer[buf_id].length;
}
printf("len: %d bytes\n",length);
}
void show(int dir_id) //顯示目錄及文件的核心函數(shù),用了遞歸思想
{
for(int i=0;i<dir[dir_id].file_count;i++)
show_file(dir[dir_id].child_file[i]);
for(i=0;i<dir[dir_id].dir_count;i++)
show_dir(dir[dir_id].child_dir[i]);
}
void list() //顯示文件及目錄的主調(diào)函數(shù)
{
show(curr); //該函數(shù)的參數(shù)表示根目錄的索引
printf("\n%d files.\n",curr_dir->file_count); //統(tǒng)計文件數(shù)
printf("\n%d dirs.\n",curr_dir->dir_count); //統(tǒng)計目錄數(shù)
}
void write_bit(int pos,int type) //寫回目錄節(jié)點、文件節(jié)點或磁盤塊的占用標(biāo)志
{ //type為0時,寫目錄;
if(type==0) //type為1時,寫文件;
{ //type為2時,寫磁盤塊
fseek(fp,sizeof(int)*(pos+3),SEEK_SET); //該函數(shù)只有在創(chuàng)建和刪除時才調(diào)用
fwrite(&dir_flag[pos],sizeof(int),1,fp);
}
else if(type==1)
{
fseek(fp,sizeof(int)*(DIR_NUM+pos+3),SEEK_SET);
fwrite(&file_flag[pos],sizeof(int),1,fp);
}
else
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+pos+3),SEEK_SET);
fwrite(&block_flag[pos],sizeof(int),1,fp);
}
}
void write_inode(int pos,int type) //寫回目錄或文件節(jié)點的控制信息
{ //type為0時,寫目錄;
if(type==0) //type為1時,寫文件;
{ //有目錄或文件的控制信息被修改,該函數(shù)就被調(diào)用
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*pos,SEEK_SET);
fwrite(&dir[pos],sizeof(struct dir_node),1,fp);
}
else
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*pos,SEEK_SET);
fwrite(&file[pos],sizeof(struct file_node),1,fp);
}
}
void write_disk(int i,int j) //將緩沖區(qū)內(nèi)的數(shù)據(jù)寫回磁盤,這個函數(shù)較復(fù)雜
{ //首先確定寫的開始位置
int write_start=(file[i].file_length<buffer[j].offset)?file[i].file_length:buffer[j].offset;
file[i].file_length=buffer[j].length;
al_file[i]++;
int block_start=write_start/BLOCK_SIZE;
int block_offset=write_start%BLOCK_SIZE;
int length=buffer[j].length-write_start;
int extra=buffer[j].length%BLOCK_SIZE;
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+file[i].block[block_start]*BLOCK_SIZE+block_offset,SEEK_SET);
fwrite(buffer[j].buf+write_start,BLOCK_SIZE-block_offset,1,fp);
for(int k=block_start+1;k<file[i].block_count-1;k++)
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+file[i].block[k]*BLOCK_SIZE,SEEK_SET);
fwrite(buffer[j].buf+BLOCK_SIZE*k,BLOCK_SIZE,1,fp);
}
if(extra>0 && length>BLOCK_SIZE)
{
fseek(fp,sizeof(int)*(DIR_NUM+FILE_NUM+BLOCK_NUM+3)+sizeof(struct dir_node)*DIR_NUM+sizeof(struct file_node)*FILE_NUM+file[i].block[k]*BLOCK_SIZE,SEEK_SET);
fwrite(buffer[j].buf+BLOCK_SIZE*k,extra,1,fp);
}
}
void savefile(int file_id) //顯式保存文件的核心函數(shù)
{
if(open_files[file_id]>0) //如果占用緩沖區(qū),應(yīng)該釋放
{
int buf_id=get_buffer_id(file_id);
if(open_files[file_id]==2) //如果該文件以寫的方式被打開,應(yīng)先將其數(shù)據(jù)
write_disk(file_id,buf_id); //寫回磁盤
buffer[buf_id].flag=0;
open_files[file_id]=0;
}
if(al_fflag[file_id]%2!=0) //如果創(chuàng)建或刪除,需要寫回磁盤
{
write_bit(file_id,1);
al_fflag[file_id]=0;
}
if(al_file[file_id]>0) //如果控制信息被修改,需要寫回磁盤
{
write_inode(file_id,1);
al_file[file_id]=0;
for(int i=0;i<file[file_id].block_count;i++)
{
int temp=file[file_id].block[i];
if(al_bflag[temp]%2!=0) //如果磁盤塊被釋放或被占用,需要寫回磁盤
{
write_bit(temp,2);
al_bflag[temp]=0;
}
}
}
}
void save_dir(int dir_id) //保存空目錄函數(shù)
{
if(al_dflag[dir_id]%2!=0) //如果刪除或創(chuàng)建,需要寫回磁盤
{
write_bit(dir_id,0);
al_dflag[dir_id]=0;
}
if(al_dir[dir_id]>0) //如果控制信息被修改,需要寫回磁盤
{
write_inode(dir_id,0);
al_dir[dir_id]=0;
}
}
void savedir(int dir_id) //保存一個目錄,及它的所有父目錄,用了遞歸
{
if(dir_id==-1)
return;
save_dir(dir_id);
savedir(dir[dir_id].parent);
}
void save(int dir_id) //保存一個目錄及它下面的所有目錄及文件
{ //用了遞歸
for(int i=0;i<dir[dir_id].dir_count;i++)
save(dir[dir_id].child_dir[i]);
for(i=0;i<dir[dir_id].file_count;i++)
savefile(dir[dir_id].child_file[i]);
save_dir(dir_id);
}
int save_file(int parent,char *file_name) //顯式保存文件
{
int pos,index;
if((pos=search(parent,file_name,1,index))==-1)
{
printf("The file not exist in current directory!\n");
return -1;
}
savedir(parent); //保存父目錄
savefile(pos);
return pos;
}
int savefile(char *name) //保存文件的主調(diào)函數(shù)
{
int parent,p=0;
parent=get_parent(name,p);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -