实验四 Linux的文件处理.docx

上传人:b****5 文档编号:30232596 上传时间:2023-08-07 格式:DOCX 页数:20 大小:503.67KB
下载 相关 举报
实验四 Linux的文件处理.docx_第1页
第1页 / 共20页
实验四 Linux的文件处理.docx_第2页
第2页 / 共20页
实验四 Linux的文件处理.docx_第3页
第3页 / 共20页
实验四 Linux的文件处理.docx_第4页
第4页 / 共20页
实验四 Linux的文件处理.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

实验四 Linux的文件处理.docx

《实验四 Linux的文件处理.docx》由会员分享,可在线阅读,更多相关《实验四 Linux的文件处理.docx(20页珍藏版)》请在冰豆网上搜索。

实验四 Linux的文件处理.docx

实验四Linux的文件处理

实验四Linux的文件处理

1.目的要求

(1)学习和掌握gcc等Linux的开发调试环境。

(2)学习并掌握Linux的文件操作。

(3)编写并实现“学生管理系统”程序。

2.实验内容

(1)文件底层系统调用实验

●使用vi将程序清单4-1和4-2的程序输入,并在当前目录下创建文件“file.in”和文件“file.out”,尽可能的使文件“file.in”大一些。

●利用gcc分别编译这两个程序,写出编译命令和执行结果;如果不成功,尝试利用gdb调试。

编译命令:

gcc-oyunxing4_1.c

运行结果:

编译命令:

gcc-oyunxing4_2.c

运行结果:

●仔细观察这两个程序,比较标准C的文件操作和Linux的系统调用open、read、write等的使用区别。

标准C的文件操作:

是带有缓冲池的文件操作,同样的文件,读取时只需一次性。

Linux的系统调用:

直接调用底层函数,里面的while((nread=read(in,&c,sizeof(c)))>0)语句,是循环调用read函数,即访问一个数据边调用底层函数,这样会增加内外模式切换,增加负担。

●按照说明重新修改程序4-2,并使用time命令察看程序执行的时间效率上有何区别。

注意:

time中real代表程序实际运行时间

User中代表用户态运行时间

Sys中代表内核态运行时间

模拟系统调用:

命令:

time./yunxing

结果:

模拟缓冲区调用:

命令:

time./yunxing

结果:

论断:

带有缓冲区的调用会比系统调用节省时间。

●输入、编译并运行程序4-3和4-4,写出执行结果,并比较他们fseek和lseek在使用方法上的异同。

4_3:

其中hole.File内容:

4_4:

Hole.file内容:

结论:

就能容上并无差异。

(2)目录信息的单层浏览

●使用vi将程序清单4-5和4-6程序输入。

●利用gcc分别编译这两个程序,写出编译命令和执行结果;如果不成功,尝试利用gdb调试。

命令:

gcc-oyunxing4_5.c

结果:

命令:

gcc-oyunxing4_6.c

结果:

●仔细观察这两个程序,比较它们的区别。

区别:

都是事先查询显示路径下的目录下的文件。

前者:

不方便操作,类似于系统的直接调用,不为应用层熟悉的方法,而且路径不灵活

后者:

把目录的操作封装成了函数,这样封锁繁杂的细节,应用层没必要知道怎么实现,只需知道怎么用,方便了应用层,可移植性大

(3)目录信息的完整浏览

●使用vi将程序清单4-7和4-8程序输入。

●利用gcc分别编译这两个程序,写出编译命令和执行结果;如果不成功,尝试利用gdb调试。

命令:

gcc-oyunxing4_7.c

结果:

命令:

gcc-oyunxing4_8c

结果:

●仔细阅读、比较这两个程序,并写出目录浏览的算法描述。

算法是递归搜索目录下的文件,主要是递归

(4)mmap、msync和munmap的使用

●使用vi将程序清单4-9程序输入。

●利用gcc编译程序,写出编译命令和执行结果;如果不成功,尝试利用gdb调试。

命令:

gcc-oyunxing4_9.c

结果:

●仔细阅读程序,并画出程序流程图。

用fseekfreadfwrite函数改变结构体43的值为143

对结构体每个数据项赋值并写入文件

定义结构体,文件

 

用mmap映射虚拟内存

用msync回写入文件

用munmap释放虚拟内存

虚拟内存图如下:

(5)学习并分别使用标准C的文件操作函数和Linux的系统调用创建一个对学生基本信息进行操作(插入、修改和删除)的C程序,学生基本信息以结构体的形式存储在文件stu.info中。

structstu_info的定义如下:

structstu_info{

charstu_num[12];

charname[10];

shortintsex;/*0为女生,1为男生*/

charmobile_phone[12];

};

3.主要仪器设备及软件

(1)硬件:

计算机、网络

(2)软件:

VMWareworkstation、RedHat9.0

4.附录:

程序清单

(1)程序清单4-1

#include

#include

intmain(void)

{

charc;

FILE*in,*out;

if((in=fopen("file.in","r"))==NULL)

{

perror("fileopenerror!

");

exit(0);

}

out=fopen("file.out","w");

while((c=fgetc(in))!

=EOF)

fputc(c,out);

fclose(in);

fclose(out);

}

(2)程序清单4-2

#include

#include

#include

intmain()

{

//charblock[1024];

charc;

intin,out;

intnread;

in=open("file.in",O_RDONLY);

out=open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);

//将注释打开,并将两条语句的后一句注释掉,重新编译执行。

//while((nread=read(in,block,sizeof(block)))>0)

while((nread=read(in,&c,sizeof(c)))>0)

//write(out,block,nread);

write(out,&c,nread);

close(in);

close(out);

}

(3)程序清单4-3

#include

#include

#include

#include

#include

charbuf1[]="abcdefghij";

charbuf2[]="ABCDEFGHIJ";

voiderr_exit(char*err_s)

{

perror(err_s);

exit

(1);

}

intmain(void)

{

FILE*fp;

if((fp=fopen("hole.file","w"))==NULL)

err_exit("fileopenfail!

");

if(fwrite(buf1,sizeof(buf1),1,fp)!

=1)

err_exit("filewritebuf1error!

");

if(fseek(fp,40,SEEK_SET)==-1)

err_exit("fseekerror!

");

if(fwrite(buf2,strlen(buf2),1,fp)!

=1)

err_exit("filewritebuf2error!

");

fclose(fp);

}

(4)程序清单4-4

#include

#include

#include

#include

#include

charbuf1[]="abcdefghij";

charbuf2[]="ABCDEFGHIJ";

voiderr_exit(char*err_s)

{

perror(err_s);

exit

(1);

}

intmain(void)

{

intfd;

if((fd=open("hole.file",O_WRONLY|O_CREAT/*|O_APPEND,0644*/))==-1)

err_exit("fileopenfail!

");

if(write(fd,buf1,10)!

=10)

err_exit("filewritebuf1error!

");

if(lseek(fd,40,SEEK_SET)==-1)

err_exit("lseekerror!

");

if(write(fd,buf2,10)!

=10)

err_exit("filewritebuf2error!

");

}

(5)程序清单4-5

#include

#include

#include

intmain()

{

DIR*pDir=opendir(“MyDirectory”);

structdirent*pDirent;

structstatvStat;

if(pDir==NULL)

{

printf(“Can’topenthedirectory\”MyDirectory\”);

return1;

}

while((pDirent=readdir(pDir))!

=NULL)

{

lstat(pDirent->d_name,&vStat);

if(S_ISDIR(vStat.st_mode))

printf(“Directory:

%s\n”,pDirent->d_name);

else

printf(“File:

%s\n”,pDirent->d_name);

}

closedir(pDir);

return0;

}

(6)程序清单4-6

#include

#include

#include

intprintDir(char*path)

{

DIR*pDir=opendir(path);

structdirent*pDirent;

structstatvStat;

if(pDir==NULL)

{

printf(“Can’topenthedirectory:

%s”,path);

return-1;

}

while((pDirent=readdir(pDir))!

=NULL)

{

lstat(pDirent->d_name,&vStat);

if(S_ISDIR(vStat.st_mode))

printf(“Directory:

%s\n”,pDirent->d_name);

else

printf(“File:

%s\n”,pDirent->d_name);

}

closedir(pDir);

return0;

}

intmain()

{

char*dirPath;

printf(“pleaseinputbrowsedir’spath:

”);

scanf(“%s”,dirPath);

if(printDir(dirPath)==0)

return0;

else

return-1;

}

(7)程序清单4-7

/*Westartwiththeappropriateheadersandthenafunction,printdir,

whichprintsoutthecurrentdirectory.

Itwillrecurseforsubdirectories,usingthedepthparameterisusedforindentation.*/

#include

#include

#include

#include

#include

voidprintdir(char*dir,intdepth)

{

DIR*dp;

structdirent*entry;//定义目录结构体

structstatstatbuf;//文件属性结构体

if((dp=opendir(dir))==NULL){

fprintf(stderr,"cannotopendirectory:

%s\n",dir);

return;

}

chdir(dir);//改变工作目录

while((entry=readdir(dp))!

=NULL){

lstat(entry->d_name,&statbuf);//读取符号文件文件属性

if(S_ISDIR(statbuf.st_mode)){

/*Foundadirectory,butignore.and..*/

if(strcmp(".",entry->d_name)==0||

strcmp("..",entry->d_name)==0)

continue;

printf("%*s%s/\n",depth,"",entry->d_name);

/*Recurseatanewindentlevel*/

printdir(entry->d_name,depth+4);

}

elseprintf("%*s%s\n",depth,"",entry->d_name);

}

chdir("..");//返回

closedir(dp);

}

/*Nowwemoveontothemainfunction.*/

intmain()

{

printf("Directoryscanof/home:

\n");

printdir("/home",0);

printf("done.\n");

exit(0);

}

(8)程序清单4-8

/*Westartwiththeappropriateheadersandthenafunction,printdir,

whichprintsoutthecurrentdirectory.

Itwillrecurseforsubdirectories,usingthedepthparameterisusedforindentation.*/

#include

#include

#include

#include

#include

voidprintdir(char*dir,intdepth)

{

DIR*dp;

structdirent*entry;

structstatstatbuf;

if((dp=opendir(dir))==NULL){

fprintf(stderr,"cannotopendirectory:

%s\n",dir);

return;

}

chdir(dir);

while((entry=readdir(dp))!

=NULL){

lstat(entry->d_name,&statbuf);

if(S_ISDIR(statbuf.st_mode)){

if(strcmp(".",entry->d_name)==0||

strcmp("..",entry->d_name)==0)

continue;

printf("%*s%s/\n",depth,"",entry->d_name);

printdir(entry->d_name,depth+4);

}

elseprintf("%*s%s\n",depth,"",entry->d_name);

}

chdir("..");

closedir(dp);

}

/*Nowwemoveontothemainfunction.*/

intmain(intargc,char*argv[])

{

char*topdir,pwd[2]=".";

if(argc!

=2)

topdir=pwd;

else

topdir=argv[1];

printf("Directoryscanof%s\n",topdir);

printdir(topdir,0);

printf("done.\n");

exit(0);

}

(9)程序清单4-9

/*WestartbydefiningaRECORDstructure

andthencreateNRECORDSversionseachrecordingtheirnumber.

Theseareappendedtothefilerecords.dat.*/

#include

#include

#include

#include

typedefstruct{

intinteger;

charstring[24];

}RECORD;

#defineNRECORDS(100)

intmain()

{

RECORDrecord,*mapped;

inti,f;

FILE*fp;

fp=fopen("records.dat","w+");/可写方式打开

for(i=0;i

record.integer=i;

sprintf(record.string,"RECORD-%d",i);//把整数I转换成字符串保存在record.string

fwrite(&record,sizeof(record),1,fp);//写入一个record的记录

}

fclose(fp);

/*Wenowchangetheintegervalueofrecord43to143

andwritethistothe43rdrecord'sstring.*/

fp=fopen("records.dat","r+");/可读方式打开

fseek(fp,43*sizeof(record),SEEK_SET);

fread(&record,sizeof(record),1,fp);

record.integer=143;

sprintf(record.string,"RECORD-%d",record.integer);

fseek(fp,43*sizeof(record),SEEK_SET);

fwrite(&record,sizeof(record),1,fp);

fclose(fp);//用fseekfreadfwrite函数改变值

/*Wenowmaptherecordsintomemory

andaccessthe43rdrecordinordertochangetheintegerto243

(andupdatetherecordstring),againusingmemorymapping.*/

f=open("records.dat",O_RDWR);//文件描述符

mapped=(RECORD*)mmap(0,NRECORDS*sizeof(record),

PROT_READ|PROT_WRITE,MAP_SHARED,f,0);

mapped[43].integer=243;

sprintf(mapped[43].string,"RECORD-%d",mapped[43].integer);

msync((void*)mapped,NRECORDS*sizeof(record),MS_ASYNC);//立即写入文件

munmap((void*)mapped,NRECORDS*sizeof(record));//解除映射

close(f);

exit(0);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1