资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,2017/1/18,#,第四章 文件操作与文件管理,基本要求,掌握,Linux,文件系统的实现,系统调用和标准,I/O,库,文件属性目录的实现和操作,系统数据文件,文件锁,高级,I/O,。,Linux,平台下文件编程,在,Linux,平台下对文件编程可以使用两类函数:,Linux,操作系统文件,API,;,C,语言,I/O,库函数。,前者依赖于,Linux,系统调用,后者实际上与操作系统是独立的,因为在任何操作系统下,使用,C,语言,I/O,库函数操作文件的方法都是相同的。,Linux,文件,API-,创建,创建,int create(const char*filename,mode_t mode);,参数,mode,指定新建文件的存取权限,它同,umask,一起决定文件的最终权限(,mode&umask).,umask,代表了文件在创建时需要去掉的一些存取权限。,umask,可通过系统调用,umask(),来改变:,int umask(int newmask);,该调用将,umask,设置为,newmask,,然后返回旧的,umask,,它只影响读、写和执行权限。,Linux,文件,API-,创建,mode,可以是以下情况的组合,,可以通过上述宏进行,“,或,”,逻辑产生标志。,标志,含义,S_IRUSR,用户可以读,S_IWUSR,用户可以写,S_IXUSR,用户可以执行,S_IRWXU,用户可以读、写、执行,S_IRGRP,组可以读,S_IWGRP,组可以写,S_IXGRP,组可以执行,S_IRWXG,组可以读写执行,Linux,文件,API-,创建,mode,可以是以下情况的组合,,可以通过上述宏进行,“,或,”,逻辑产生标志。,标志,含义,S_IROTH,其他人可以读,S_IWOTH,其他人可以写,S_IXOTH,其他人可以执行,S_IRWXO,其他人可以读、写、执行,S_ISUID,设置用户执行,ID,S_ISGID,设置组的执行,ID,Linux,文件,API-,创建,用数字来表示:,Linux,总共用,5,个数字来表示文件的各种权限:,第一位表示设置用户,ID,;,第二位表示设置组,ID,;,第三位表示用户自己的权限位;,第四位表示组的权限;,最后一位表示其他人的权限。每个数字可以取,1(,执行权限,),、,2(,写权限,),、,4(,读权限,),、,0(,无,),或者是这些值的和。,Linux,文件,API-,创建,用数字来表示:,例如,要创建一个用户可读、可写、可执行,但是组没有权限,其他人可以读、可以执行的文件,并设置用户,ID,位。,应该使用的模式是,1(,设置用户,ID),、,0(,不设置组,ID),、,7(1+2+4,,读、写、执行,),、,0(,没有权限,),、,5(1+4,,读、执行,),即,10705,Linux,文件,API-,打开,打开,int open(const char*pathname,int flags);,int open(const char*pathname,int flags,mode_t mode);,如果文件打开成功,,open,函数会返回一个文件描述符,以后对该文件的所有操作就可以通过对这个文件描述符进行操作来实现。,open,函数有两个形式,其中,pathname,是要打开的文件名,(,包含路径名称,缺省是认为在当前路径下面,),。,Linux,文件,API-,打开,打开,flags,可以是下面的一个值或者是几个值的组合,,O_RDONLY,、,O_WRONLY,、,O_RDWR,三个标志只能使用任意的一个,。,Linux,文件,API-,打开,打开,如果使用了,O_CREATE,标志,则使用的函数是,int open(const char*pathname,int flags,mode_t mode);,这时要指定,mode,标志,用来表示文件的访问权限。以,O_CREAT,为标志的,open,实际上实现了文件创建的功能。,例如:,open(test,O_CREAT,10705);,open(test,O_CREAT,S_IRWXU|S_IROTH|S_IXOTH|S_ISUID);,Linux,文件,API-,读写,读写,Linux,中提供文件读写的系统调用是,read,、,write,函数:,int read(int fd,const void*buf,size_t length);,int write(int fd,const void*buf,size_t length);,参数,buf,为指向缓冲区的指针,,length,为缓冲区的大小(以字节为单位)。,Linux,文件,API-,读写,int read(int fd,const void*buf,size_t length);,函数,read,实现从文件描述符,fd,所指定的文件中读取,length,个字节到,buf,所指向的缓冲区中,返回值为实际读取的字节数。,int write(int fd,const void*buf,size_t length);,函数,write,实现将把,length,个字节从,buf,指向的缓冲区中写到文件描述符,fd,所指向的文件中,返回值为实际写入的字节数。,Linux,文件,API-,定位,定位:,对于随机文件,我们可以随机的指定位置读写,使用如下函数进行定位:,int lseek(int fd,offset_t offset,int whence);,lseek(),将文件读写指针相对,whence,移动,offset,个字节。操作成功时,返回文件指针相对于文件头的位置。参数,whence,可使用下述值:,SEEK_SET,:相对文件开头,SEEK_CUR,:相对文件读写指针的当前位置,SEEK_END,:相对文件末尾,Linux,文件,API-,定位,定位:,offset,可取负值,例如下述调用可将文件指针相对当前位置向前移动,5,个字节:,lseek(fd,-5,SEEK_CUR);,由于,lseek,函数的返回值为文件指针相对于文件头的位置,因此下列调用的返回值就是文件的长度:,lseek(fd,0,SEEK_END);,Linux,文件,API-,关闭,关闭,当操作完成以后,要关闭文件,只要调用,close,即可,其中,fd,是要关闭的文件描述符,:,int close(int fd);,Linux,文件,API-,编程实例,例程:编写一个程序,在当前目录下创建用户可读写文件“,hello.txt”,,在其中写入“,Hello,software weekly”,,关闭该文件。再次打开该文件,读取其中的内容并输出在屏幕上。,Linux,文件,API-,编程实例,#include /,类型,#include /,获取文件属性,#include /,文件描述词操作,#include#define LENGTH 100,main(),int fd,len;,char strLENGTH;,fd=open(“hello.txt”,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);,/*,创建并打开文件,以读写的方式打开,用户可以读、用户可以写*,/,if(fd),write(fd,Hello,Software Weekly,strlen(Hello,software weekly);,/*,写入,Hello,software weekly,字符串*,/,close(fd);,fd=open(“hello.txt”,O_RDWR);,/,以读写方式打开,len=read(fd,str,LENGTH);,/*,读取文件内容*,/,strlen=0;printf(%sn,str);close(fd);,Linux,文件,API-,编程实例,编译并运行,执行结果如下,rootdl root#gcc g o hello./hello.c,rootdl root#./hello,Hello,software weekly,C,语言库函数,C,库函数的文件操作实际上是独立于具体的操作系统平台的,不管是在,DOS,、,Windows,、,Linux,中都是这些函数,.,C,语言库函数,-,创建和打开,创建和打开,FILE*fopen(const char*path,const char*mode);,fopen(),实现打开指定文件,,参数,path,字符串包含欲打开的文件路径及文件名,,,mode,为打开模式,.,返回值:文件指针名。必须被说明为,FILE,类型的指针变量。,C,语言库函数,-,创建和打开,C,语言中支持的打开模式如下表,其中,b,用于区分二进制文件和文本文件,在,DOS,、,Windows,系统中是有区分的,但,Linux,不区分二进制文件和文本文件。,标志,含义,r,rb,以只读方式打开,w,wb,以只写方式打开。如果文件不存在,则创建该文件,否则文件被截断,a,ab,以追加方式打开。如果文件不存在,则创建该文件,r+,r+b,rb+,以读写方式打开,+,w+b,wh+,以读写方式打开。如果文件不存在时,创建新文件,否则文件被截断,a+,a+b,ab+,以读和追加方式打开。如果文件不存在,创建新文件,C,语言库函数,-,读写,读写:,C,库函数支持以字符、字符串等为单位,支持按照某种格式进行文件的读写,这一组函数为:,int fgetc(FILE*stream);,从流中读一个字符,int fputc(int c,FILE*stream);,送一个字符到流中,char*fgets(char*s,int n,FILE*stream);,从流中读取一字符串,int fputs(const char*s,FILE*stream);,送一个字符串到流中,C,语言库函数,-,读写,int fprintf(FILE*stream,const char*format,.);,传送格式化输出到一个文件中,成功时返回转换的字节数,失败时返回一个负数。,fprintf(stream,%s%c,s,c);fprintf(stream,%dn,i);,int fscanf(FILE*stream,const char*format,.);,从一个流中执行格式化输入,if(fscanf(stdin,%d,&i),printf(The integer read was:%dn,i);,C,语言库函数,-,读写,读写:,size_t fread(void*ptr,size_t size,size_t n,FILE*stream);,size_t fwrite(const void*ptr,size_t size,size_t n,FILE*stream);,fread(),实现从流,stream,中读取,n,个字段,每个字段为,size,字节,并将读取的字段放入,ptr,所指的字符数组中,返回实际已读取的字段数。,write(),实现从缓冲区,ptr,所指的数组中把,n,个字段写到流,stream,中,每个字段长为,size,个字节,返回实际写入的字段数。,C,语言库函数,-,定位,定位:,C,库函数还提供了读写过程中的定位能力,这些函数包括:,int fgetpos(FILE*stream,fpos_t*pos);,/,将文件流的文件位置指示符存储在,pos,变量中,int fsetpos(FILE*stream,const fpos_t*pos,);,/,将文件指针定位在,pos,指定的位置上,返回值:成功返回,0,,否则返回非,0,。,C,语言库函数,-,定位实例,#include,void main(void),FILE *fp;,fpos_t pos;,char buffer50;,if(fp=fopen(test.txt,rb)=NULL),/*,以只读方式打
展开阅读全文