操作系統(tǒng)磁盤文件管理源碼
《操作系統(tǒng)磁盤文件管理源碼》由會員分享,可在線閱讀,更多相關(guān)《操作系統(tǒng)磁盤文件管理源碼(50頁珍藏版)》請?jiān)谘b配圖網(wǎng)上搜索。
1、頁眉
#include
2、ISK_SIZE sizeof(struct direct) // 根目錄大小 // 路徑最大長 度為 #define DIR_MAXSIZE 1024 1KB 〃最大子目錄數(shù) 5 #define MSD 5 //最大文件深度為 5 #define MOFN 5 // 最大寫入文字長度 128KB #define MAX_WRITE 1024*128 struct fatitem /* size 8*/ int item; /*存放文件下一個(gè)磁盤的指針*/ { char em_disk;/* 磁盤塊是否空閑標(biāo)志位 0空閑*/ }; 頁腳 頁眉 struct dire
3、ct { /*-----文件控制快信息-----*/ struct FCB { char name[9]; /*文件/目錄名 8位*/ char property; /*屬性1位目錄 0位普通文件*/ int size; /*文件/目錄字節(jié)數(shù)、盤塊數(shù))*/ int firstdisk; /*文件/目錄 起始盤塊號*/ int next; /*子目錄起始盤塊號*/ int sign; /*1是根目錄 0不是根目錄*/ }directitem[MSD+2]; }; struct opentable struct openttableitem { char name[
4、9]; /* 文件名 */ */ 起始盤塊號 int firstdisk; /* 頁腳 頁眉 int size; /*文件的大小*/ }openitem[MOFN]; int cur_size; /*當(dāng)前打文件的數(shù)目*/ }; struct fatitem *fat; /*FAT 表*/ struct direct *root; /* 根目錄 */ struct direct *cur_dir; /* 當(dāng)前目錄 */ struct opentable u_opentable; /* 文件打開表 */ int fd=-1; /*文件打開表的序號*/ char *buff
5、erdir; /*記錄當(dāng)前路徑的名稱*/ 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 *nam
6、e); 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; 表地址,引導(dǎo)區(qū)向后偏計(jì)算 fat = (struct fatitem *)(fdisk+DISKSIZE); /*FAT 移 1k)*/ 頁腳 頁眉
7、
/*-----初始化 FAT 表 */
fat[0].item=-1; /* 引導(dǎo)塊 */
fat[0].em_disk=1;
for(i=1;i 8、.em_disk = 0;
/*
*/
根目錄的地址*/
root = (struct direct *)(fdisk+DISKSIZE+FATSIZE); /*
/*初始化目錄*/
/*
*/指向當(dāng)前目錄的目錄項(xiàng)頁腳
頁眉
root->directitem[0].sign = 1;
root->directitem[0].firstdisk = ROOT_DISK_NO;
strcpy(root->directitem[0].name,.);
root->directitem[0].next = root->directitem[0].firstdisk;
ro 9、ot->directitem[0].property = 1;
root->directitem[0].size = ROOT_DISK_SIZE;
/*
指向上一級目錄的目錄項(xiàng)
*/
root->directitem[1].sign = 1;
root->directitem[1].firstdisk = ROOT_DISK_NO;
strcpy(root->directitem[1].name,..);
root->directitem[1].next = root->directitem[0].firstdisk;
root->directitem[1].p 10、roperty = 1;
root->directitem[1].size = ROOT_DISK_SIZE;
if((fp = fopen(disk.dat,wb))==NULL)
{
printf(Error:\n Cannot open file \n);
return;
}
for(i=2;i 11、
root->directitem[i].next = -1;
root->directitem[i].property = 0;
root->directitem[i].size = 0;
} if((fp = fopen(disk.dat,wb))==NULL)
printf(Error:\n Cannot open file \n);
return;
}
把虛擬磁盤空間保存到磁盤文件中 if(fwrite(fdisk,MEM_D_SIZE,1,fp)!=1)/**/
{
printf(Error:\n File write error! \n);
}
fclose 12、(fp);
}
void enter()
頁腳
頁眉
{
FILE *fp;
int i;
fdisk = (char *)malloc(MEM_D_SIZE*sizeof(char));/* 申請 1M 空間*/
if((fp=fopen(disk.dat, b))==NULL)
printf(Error:\nCannot open file\n);
return;
}
讀入虛擬磁盤 disk.dat /* if(!fread(fdisk,MEM_D_SIZE,1,fp)) 把磁盤文件空間
(內(nèi)存)*/
{
printf(Error:\nCannot read 13、 file\n);
exit(0);
}
fat = (struct fatitem *)(fdisk+DISKSIZE); /* 找到 FAT表地址 */
找到根目錄地址 root = (struct direct *)(fdisk+DISKSIZE+FATSIZE);/**/ fclose(fp);
初始化用戶打開表/* */
for(i=0;i 14、penitem[i].size = 0;
u_opentable.cur_size = 0;
cur_dir = root; /* 當(dāng)前目錄為根目錄*/
bufferdir = (char *)malloc(DIR_MAXSIZE*sizeof(char));
strcpy(bufferdir,Root:);
}
void halt()
{
FILE *fp;
int i;
if((fp=fopen(disk.dat,wb))==NULL)
{
printf(Error:\nCannot open file\n);
return;
}
內(nèi)容讀入磁盤/*if(!fw 15、rite(fdisk,MEM_D_SIZE,1,fp)) 內(nèi)存(把虛擬磁盤空間)頁腳
頁眉
文件 disk.dat */
printf(Error:\nFile write error!\n);
}
fclose(fp);
free(fdisk);
free(bufferdir);
return;
}
int create(char *name)
{
int i,j;
if(strlen(name)>8)/* 文件名大于 8 位*/
return(-1);
for(j=2;j 16、rcmp(cur_dir->directitem[j].name,name))
頁腳
頁眉
break;
}
if(j 17、T_DISK_NO+1;j 18、item[i].next = j;
cur_dir->directitem[i].property = 0;
*/
/*
fd = open(name);
return 0;
int open(char *name)
{
int i, j;
for(i=2;i 19、i].property==1)
return(-4);
/* 文件是否打開 */
for(j=0;j 20、rstdisk==-1)
break;
}
/* 填寫表項(xiàng)的相關(guān)信息 */
u_opentable.openitem[j].firstdisk = cur_dir->directitem[i].firstdisk;
strcpy(u_opentable.openitem[j].name,name);
u_opentable.openitem[j].size = cur_dir->directitem[i].size;
u_opentable.cur_size++;
/* 返回用戶打開表表項(xiàng)的序號 */
return(j);
}
int close(char *name) 21、
int i;
for(i=0;i 22、0;
}
int write(int fd, char *buf, int len)
char *first;
int item, i, j, k;
int ilenl, ilen2, modlen, temp;
/* 用$字符作為空格 #字符作為換行符 */
char Space = 32;
char Endter= \n;
for(i=0;i 23、表對應(yīng)表項(xiàng)第一個(gè)盤塊號
item = u_opentable.openitem[fd].firstdisk;
*/ /* 找到當(dāng)前目錄所對應(yīng)表項(xiàng)的序號
for(i=2;i 24、}
/*-----計(jì)算出該文件的最末地址 ——*/
first = fdisk+item*DISKSIZE+u_opentable.openitem[fd].size%DISKSIZE;
/*-----如果最后磁盤塊剩余的大小大于要寫入的文件的大小 */
if(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE>len)
{
strcpy(first,buf);
u_opentable.openitem[fd].size
u_opentable.openitem[fd].size+len;
cur_dir->directitem[ 25、temp].size
cur_dir->directitem[temp].size+len;
}
else
{
for(i=0;i<(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);i++)
{/*寫一部分內(nèi)容到最后一塊磁盤塊的剩余空間(字節(jié))*/
first[i] = buf [i];
}
還剩下多少字節(jié)未存字節(jié))(/*----計(jì)算分配完最后一塊磁盤的剩余空間儲
*/
頁腳
頁眉
ilen1 = len-(DISKSIZE-u_opentable.openitem[fd].size%DISKSIZE);
ilen 26、2 = ilen1/DISKSIZE;
modlen = ilen1%DISKSIZE;
if(modlen>0)
ilen2 = ilen2+1;/*-- 還需要多少塊磁盤塊-*/
for(j=0;j 27、盤塊的起始地址-*/
if(j==ilen2-1) /*-- 如果是最后要分配的一塊 -*/
{
for(k=0;k 28、isk = 1; /*-- 置找到的磁盤快的空閑標(biāo)志位為已分配 -*/
fat[i].item = -1; /*-- 它的指針為 -1 (即沒有下一塊 )-*/
}
修改長度 /*-- -*/
u_opentable.openitem[fd].size
u_opentable.openitem[fd].size+len;
cur_dir->directitem[temp].size
cur_dir->directitem[temp].size+len;
}
return 0;
}
int read(int fd, char *buf)
頁腳
頁眉
{
int 29、len = u_opentable.openitem[fd].size;
char *first;
int i, j, item;
int ilenl, modlen;
item = u_opentable.openitem[fd].firstdisk;
ilenl = len/DISKSIZE;
modlen = len%DISKSIZE;
if(modlen!=0)
ilen1 = ilen1+1;/*--計(jì)算文件所占磁盤的塊數(shù)-*/
-*/ first = fdisk+item*DISKSIZE; /*--計(jì)算文件的起始位置
for(i=0;i 30、
{
if(i==ilen1-1)/*-- 如果在最后一個(gè)磁盤塊-*/
{
for(j=0;j 31、har *name)
{
int i,cur_item,item,temp;
for(i=2;i 32、的
錄-*/
return(-3);
-*/則不能刪除,退出for(i=0;i 33、disk = 0;
item = temp;
}
釋放目錄項(xiàng)/* */
頁腳
頁眉
cur_dir->directitem[curjtem].sign = 0;
cur_dir->directitem[curjtem].firstdisk = -1;
strcpy(u_opentable.openitem[curjtem].name,\);
cur_dir->directitem[cur_item].next = -1;
cur_dir->directitem[cur_item].property = 0;
cur_dir->directitem[curjtem].siz 34、e = 0;
return 0;
}
int mkdir(char *name)
{
int i,j;
struct direct *cur_mkdir;
if(!strcmp(name,.))
return(-4);
if(!strcmp(name,..))
return(-4);
if(strlen(name)>8) /*-如果目錄名長度大于 8位-*/
return(-1);
頁腳
頁眉
for(i=2;i 35、reak;
}
-*/ 已滿 if(i>=MSD+2) /*-目錄/ 文件
return(-2);
for(j=2;j 36、eturn(-5);
頁腳
頁眉
fat[j].em_disk=1; /*- 將該空閑塊設(shè)置為已分配-*/
/* 填寫目錄項(xiàng) */
strcpy(cur_dir->directitem[i].name,name);
cur_dir->directitem[i].firstdisk=j;
cur_dir->directitem[i].size=ROOT_DISK_SIZE;
cur_dir->directitem[i].next=j;
cur_dir->directitem[i].property=1;
/*-所創(chuàng)目錄在虛擬磁盤上的地址(內(nèi)存物理地址)-*/
cur_mkd 37、ir=(struct direct
*)(fdisk+cur_dir->directitem[i].firstdisk*DISKSIZE);
/*-初始化目錄-*/
/*-指向當(dāng)前目錄的目錄項(xiàng)-*/
cur_mkdir->directitem[0].sign=0;
cur_mkdir->directitem[0].firstdisk=cur_dir->directitem[i].firstdisk;
strcpy(cur_mkdir->directitem[0].name,.);
cur_mkdir->directitem[0].next=cur_mkdir->directite 38、m[0].firstdisk;
cur_mkdir->directitem[0].property=1;
cur_mkdir->directitem[0].size=ROOT_DISK_SIZE;
頁腳
頁眉
/*-指向上一級目錄的目錄項(xiàng)-*/
cur_mkdir->directitem[1].sign=cur_dir->directitem[0].sign;
cur_mkdir->directitem[1].firstdisk=cur_dir->directitem[0].firstdisk;
strcpy(cur_mkdir->directitem[1].name,..); 39、
cur_mkdir->directitem[1].next=cur_mkdir->directitem[1].firstdisk;
cur_mkdir->directitem[1].property=1;
cur_mkdir->directitem[1].size=ROOT_DISK_SIZE;
for(i=2;i 40、ame,\);
cur_mkdir->directitem[i].next=-1;
cur_mkdir->directitem[i].property=0;
cur_mkdir->directitem[i].size=0;
}
return 0;
}
int rmdir(char *name)
{
頁腳
頁眉
int i,j,item;
struct direct *temp_dir;
/*-檢查當(dāng)前目錄項(xiàng)中有無該目錄 -*/
for(i=2;i 41、
break;
if(i>=MSD+2) /*-沒有這個(gè)文件或目錄 -*/ return(-1);
if(cur_dir->directitem[i].property!=T)/*- 刪除的不是目錄 -*/
return(-3);
-*//*-判斷要?jiǎng)h除的目錄有無子目錄
temp_dir=(struct direct *)(fdisk+cur_dir->directitem[i].next*DISKSIZE);
for(j=2;j 42、f(j 43、operty=0;
cur_dir->directitem[i].size=0;
return 0;
}
void dir()
{
int i;
for(i=2;i 44、item[i].size);
else
printf(\ < 目錄 >\t\n);
}
}
}
int cd(char *name)
{
int i,j,item;
char *str;
char *temp,*point,*point1;
struct direct *temp_dir;
temp_dir=cur_dir;
str=name;
if(!strcmp(\\\,name))
{
cur_dir = root;
strcpy(bufferdir,Root:);
頁腳
頁眉
return 0;
}
temp = (char *) 45、malloc(DIR_MAXSIZE*sizeof(char));/*- 最長路徑名字分配空
問-*/
for(i=0;i<(int)strlen(str);i++)
temp[i]=str[i];
temp[i]=\0;
for(j=0卜MSD+2;j++) /*-查找該子目錄是否在當(dāng)前目錄中 -*/
{
if(!strcmp(temp_dir->directitem[j].name,temp)) break;
}
*/ free(temp);/* 釋放申請的臨時(shí)空間
//if(temp_dir->directitem[j].property!=1) /*- 打開的不是目 46、錄-*/
//return(-2);
-*/ 不在當(dāng)前目錄 if(j>=MSD+2) /*- return(-1);
item=temp_dir->directitem[j].firstdisk;
/*- 當(dāng)前目錄在磁盤中位置 -*/
temp_dir=(struct direct *)(fdisk+item*DISKSIZE);
if(!strcmp(..,name))
{
if(cur_dir->directitem[j-1].sign!=1) /*- 如果上級目錄不是根目錄 -*/
{
point=strchr(bufferdir,\\); // 查找字符串 buff 47、erdir 中首次出現(xiàn)字符 \ 的
位置
while(point!=NULL)
{
point1=point+1; /*- 減去 \ 所占的空間 , 記錄下次查找的起始地址 -*/
point=strchr(point1,\\);
}
將上一級目錄刪除 *(point1-1)=\0; /*- -*/
}
頁腳
頁眉
else
{
//if(name[0] !=\\)
bufferdir = strcat(bufferdir,\\\); /*- 修改當(dāng)前目錄 -*/
bufferdir = strcat(bufferdir,name);
}
-*/ 48、/*-cur_dir=temp_dir; 將當(dāng)前目錄確定下來 return 0;
} void show()
{
printf(%s>,bufferdir);
}
void print()
{
printf(*
*******************************************************
*\n);
文件系統(tǒng)設(shè)計(jì)
printf(*
******************************************
**\n);
*\n); 命令格式printf(*\t 說明
printf(*\tcd 目錄名 *\n) 49、; 更改當(dāng)前目錄
頁腳
頁眉
printf(*\tmkdir 目錄名 創(chuàng)建子目錄 *\n);
刪除子目錄 printf(*\trmdir 目錄名 *\n);
顯示當(dāng)前目錄的子目錄 *\n); printf(*\tdir
創(chuàng)建文件 *\n); printf(*\tcreate 文件名
printf(*\tdel 文件名 刪除文件 *\n);
*\n); 打開文件printf(*\topen 文件名
關(guān)閉文件 *\n); 文件名printf(*\tclose
printf(*\tread 讀文件 *\n);
*\n); printf(*\twrite 寫文件
*\n); p 50、rintf(*\texit 退出系統(tǒng)
printf(*
*******************************************************
*\n);
}
void main()
{
FILE *fp;
char ch;
char a[100];
char code[11][10];
char name[10];
int i,flag,r_size;
頁腳
頁眉
char *contect;
contect = (char *)malloc(MAX_WRITE*sizeof(char));
i 51、f((fp=fopen(disk.dat,
b))==NULL)
{
printf(You have not format,Do you want format?(y/n));
scanf(%c,&ch);
if(ch==y)
{
initfile();
printf(Successfully format! \n);
else
return;
}
}
enter();
print();
頁腳
頁眉
show();
strcpy(code[0],exit);
strcpy(code[1],create);
strcpy(code[2],open);
s 52、trcpy(code[3],close);
strcpy(code[4],write);
strcpy(code[5],
ead);
strcpy(code[6],del);
strcpy(code[7],mkdir);
strcpy(code[8], mdir);
strcpy(code[9],dir);
strcpy(code[10],cd);
while(1)
{
scanf(%s,a);
for(i=0;i<11;i++)
{
if(!strcmp(code[i],a))
break;
}
頁腳
頁眉
switch(i)
{
case 0: / 53、/ 退出文件系統(tǒng) free(contect);
halt();
return;
case 1: // 創(chuàng)建文件
scanf(%s,name);
flag = create(name);
if(flag==-1)
{
printf(Error: \n The length is too long !\n);
}
else if(flag==-2)
{
printf(Error: \n The direct item is already full !\n);
}
else if(flag==-3)
{
printf(Error: \n The number of 54、openfile is too much !\n);
}
頁腳
頁眉
else if(flag==-4)
{
printf(Error: \n The name is already in the direct !\n);
}
else if(flag==-5)
{
printf(Error: \n The disk space is full!\n);
else
{
printf(Successfully create a file! \n);
}
show();
break;
case 2:〃打開文件
scanf(%s,name);
fd = open 55、(name);
if(fd == -1)
{
printf(Error: \n The open file not exit! \n);
頁腳
頁眉
}
else if(fd == -2)
{
printf(Error: \n The file have already opened! \n);
else if(fd == -3)
{
printf(Error: \n The number of open file is too much! \n);
}
else if(fd == -4)
{
printf(Error: \n It is a direct, 56、can not open for read or write!
\n);
}
else
{
printf(Successfully opened! \n);
}
show();
break;
case 3://關(guān)閉文件
頁腳
頁眉
scanf(%s,name);
flag = close(name);
if(flag == -1)
printf(Error:\n The file is not opened ! \n);
}
else
{
printf(Successfully closed! \n);
}
show();
break;
c 57、ase 4:〃寫文件
if(fd ==-1)
{
printf(Error:\n The file is not opened ! \n);
}
else
{
printf(Please input the file contect:);
scanf(%s,contect);
頁腳
頁眉
flag=write(fd,contect,strlen(contect));
if(flag == 0)
{
printf(Successfully write! \n);
}
else
{
printf(Error:\n The disk size is not eno 58、ugh! \n);
}
}
show();
break;
case 5:〃 讀文件
if(fd ==-1)
{
printf(Error:\n The file is not opened ! \n);
}
else
{
flag = read(fd,contect);
if(flag == 0)
頁腳
頁眉
{
for(i=0;i 59、除文件
scanf(%s,name);
flag = del(name);
if(flag == -1)
{
printf(Error:\n The file not exit! \n);
}
else if(flag == -2)
{
printf(Error:\n The file is opened,please first close it ! \n);
頁腳
頁眉
else if(flag == -3)
{
printf(Error:\n The delete is not file ! \n);
}
else
{
printf(Succe 60、ssfully delete! \n);
}
show();
break;
case 7://創(chuàng)建子目錄
scanf(%s,name);
flag = mkdir(name);
if(flag == -1)
{
printf(Error:\n The length of name is to long! \n);
}
else if(flag == -#)
{
printf(Error:\n The direct item is already full ! \n);
}
頁腳
頁眉
else if(flag == -3)
{
printf(Err 61、or:\n The name is already in the direct ! \n);
}
else if(flag == -4)
{
the the name of or . can not as \n printf(Error: direct!\n);
}
else if(flag == -5)
{
printf(Error: \n The disk space is full!\n);
}
else if(flag == 0)
{
printf(Successfully make dircet! \n);
show();
break;
case 8:1 62、1刪除子目錄
scanf(%s,name);
頁腳
頁眉
flag = rmdir(name);
if(flag == -1)
{
printf(Error:\n The direct is not exist! \n);
}
else if(flag == -2)
{
printf(Error:\nThe direct has son direct ,please first remove the son dircct!\n);
}
else if(flag == -3)
{
printf(Error:\n The remove is not direct ! 63、\n);
}
printf(Successfully remove dircet! \n);
}
show();
break;
顯示當(dāng)前子目錄 case 9:〃 頁腳
頁眉
dir();
show();
break;
case 10://更改當(dāng)前目錄
scanf(%s,name);
flag = cd(name);
if(flag == -1)
{
printf(Error:\n The path no correct!\n);
}
else if(flag == -2)
printf(Error:\nThe opened is not direct!\n);
}
show();
break;
default:
printf(\
Error!\n The command is wrong! \n);
show();
頁腳
頁眉
頁腳
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 110中國人民警察節(jié)(筑牢忠誠警魂感受別樣警彩)
- 2025正字當(dāng)頭廉字入心爭當(dāng)公安隊(duì)伍鐵軍
- XX國企干部警示教育片觀后感筑牢信仰之基堅(jiān)守廉潔底線
- 2025做擔(dān)當(dāng)時(shí)代大任的中國青年P(guān)PT青年思想教育微黨課
- 2025新年工作部署會圍繞六個(gè)干字提要求
- XX地區(qū)中小學(xué)期末考試經(jīng)驗(yàn)總結(jié)(認(rèn)真復(fù)習(xí)輕松應(yīng)考)
- 支部書記上黨課筑牢清廉信念為高質(zhì)量發(fā)展?fàn)I造風(fēng)清氣正的環(huán)境
- 冬季消防安全知識培訓(xùn)冬季用電防火安全
- 2025加強(qiáng)政治引領(lǐng)(政治引領(lǐng)是現(xiàn)代政黨的重要功能)
- 主播直播培訓(xùn)直播技巧與方法
- 2025六廉六進(jìn)持續(xù)涵養(yǎng)良好政治生態(tài)
- 員工職業(yè)生涯規(guī)劃方案制定個(gè)人職業(yè)生涯規(guī)劃
- 2024年XX地區(qū)黨建引領(lǐng)鄉(xiāng)村振興工作總結(jié)
- XX中小學(xué)期末考試經(jīng)驗(yàn)總結(jié)(認(rèn)真復(fù)習(xí)輕松應(yīng)考)
- 幼兒園期末家長會長長的路慢慢地走