




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
文件系统编程2主要内容文件系统概述系统调用与库函数基本I/O系统调用文件属性及目录相关系统调用标准I/O库高级I/O库文件系统概述3文件文件可被读写的对象。具备一定权限属性,包括访问权限、类型等。文件类型普通文件(文本文件,shell脚本,二进制的可执行程序等)目录文件设备文件(字符设备文件/块设备文件)FIFO文件(如管道文件)Socket文件链接文件(硬链接文件,软链接文件)文件系统概述文件属性inode数据结构45硬连接文件硬链接文件相当于源文件的一个别名,和源文件指向相同的inode节点,系统并不为它重新分配inode。
用infoln命令可以查看到硬链接的解释是A“hardlink”isanothernameforanexistingfile。硬链接节省空间,是Linux系统整合文件系统的传统方式存在不足之处:不可以在不同文件系统的文件间建立链接只有超级用户才可以为目录创建硬链接。命令格式:
ln
[-d]
source_path
target_pathinode/root/linkab文件系统概述6软链接文件(符号链接文件)存储被链接文件的文件名(而不是inode)实现链接软链接又称为符号链接,类似于Windows中的“快捷方式”,相当于建立一个新文件,该文件指向源文件。这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。链接文件甚至可以链接不存在的文件,这就产生一般称之为"断链"的问题(或曰“现象"),链接文件甚至可以循环链接自己。类似
于编程语言中的递归。命令格式:
ln
[-s]
source_path
target_pathinode/root/linkab文件系统概述查看文件属性ls–li查看当前目录下所有文件的属性
7文件权限8文件类型9文件类型在stat.h文件中被定义为宏,采用8进制形式。数字中的第一个0表示8进制。权限修饰位文件权限修饰符包括setuid,setgid和sticky。如果设置了setuid位,则访问文件的进程的有效用户ID会被设置为当前文件的所有者。如果设置了setgid位,则访问文件的进程的有效组ID会被设置为当前文件所有者组ID。sticky位使用不多,如果一个文件设置了sticky位,则系统将尽可能使该文件常驻内存。10例如普通用户运行passwd命令来更改自己的口令,实际上最终更改的是/etc/passwd文件。但是,/etc/passwd文件是用户信息的配置文件,只有root权限的用户才能更改内容。文件系统文件系统文件及其属性的集合,提供了命名及管理机制。文件系统类型Windows文件系统:FAT16,FAT32,NTFS传统UNIX文件系统:UFS(UnixFileSystem)Linux文件系统ext2(在Linux2.0.x中首次使用)reiserfs(在Linux2.2.x中首次使用)ext3(在Linux2.4.x中首次使用)xfs(源于SGI)Jfs(源于IBM)嵌入式小型文件系统CRAMFSJFFS2yaffs21112EXT2文件系统第一个磁盘块用于引导,其余部分被分成若干组各组大小相同且顺序存放可通过组序号确定组在磁盘上的位置组的构成文件系统超级块:记录此filesystem的整体信息,包括inode/block的总量、使用量、剩余量,以及文件系统的格式与相关信息等。组描述符数据块位图inode位图inode表数据块文件系统概述13EXT2文件系统体系结构每组都有一份超级块和所有组描述信息的拷贝正常情况下内核只使用第0组的信息当组0的拷贝遭到损坏时便可根据其它组的拷贝恢复组描述符:组内各个块组的位置信息:数据块位图大小为一个块每一位顺序对应组中的一个块0表示可用1表示已用inode表存放文件及目录的inode数据inode位图表示对应的inode表空间是否已被占用文件系统概述14EXT3文件日志文件系统(journalingfilesystem)利用数据库的日志技术(log,checkpoint)3种日志方式journal,ordered,writeback日志记录在/.journal中(隐藏文件)Kjournald—5s文件系统概述15Linux的文件系统虚拟文件系统(VFS)虚拟文件系统Ext2Ext3...BufferCache设备驱动进程控制
子系统系统调用接口用户程序进程间通信调度器内存管理硬件文件系统概述16主要内容文件系统概述系统调用与库函数基本I/O系统调用文件属性及目录相关系统调用标准I/O库高级I/O库17系统调用与库函数的基本概念均以C函数形式出现系统调用Linux内核的对外接口用户程序与内核之间的唯一接口提供最小接口库函数依赖于系统调用提供较复杂功能例:标准I/O库系统调用与库函数18系统调用与库函数的结构视图系统调用与库函数19无缓存I/O与有缓存I/O无缓存I/O读/写->设备文件描述符ANSIC不支持、POSIX支持设备文件访问时使用有缓存I/O标准I/O库提供处理很多细节缓存分配以优化长度执行I/O流->FILE指针普通文件系统调用与库函数20主要内容文件系统概述系统调用与库函数基本I/O系统调用文件属性及目录相关系统调用标准I/O库高级I/O库21基本I/O系统调用文件描述符基本I/O系统调用open()/creat(),close(),read(),write(),lseek()dup()/dup2()fcntl()ioctl()基本I/O系统调用22文件描述符非负整数定义形式intfd;标准文件描述符定义(<unistd.h>)STDIN_FILENO(0)STDOUT_FILENO(1)STDERR_FILENO(2)文件操作的一般过程打开-读/写-[定位]-关闭基本I/O系统调用23文件操作相关数据类型基本I/O系统调用24出错处理UNIX风格返回值“errno”
变量(/usr/include/errno.h)externinterrno;strerror#include<string.h>char*strerror(interrnum);返回出错的字符串描述perror()#include<stdio.h>voidperror(constchar*msg);打印错误原因字符串基本I/O系统调用25open()/creat()系统调用功能打开或创建一个文件或设备头文件#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>函数原型intopen(constchar*pathname,intflags);intopen(constchar*pathname,intflags,mode_tmode);intcreat(constchar*pathname,mode_tmode);返回值成功时返回新文件描述符否则返回-1基本I/O系统调用26参数flags说明功能文件访问模式取值说明(/usr/include/fcntl.h)O_RDONLY:只读形式打开O_WRONLY:只写形式打开
O_RDWR:读写形式打开O_APPEND:追加模式打开O_TRUNC:若文件存在且为只读或只写成功打开,则将长度截为0O_CREAT:若文件不存在则创建之使用此选项时,需同时说明参数mode,说明文件的存取许可权位O_EXCL:若同时指定O_CREAT,而文件已经存在,则出错该参数可测试文件是否存在,如果不存在则创建此文件creat()函数说明等价于已参数O_CREAT|O_WRONLY|O_TRUNC执行open()基本I/O系统调用27参数mode说明定义新建文件的访问权限其他用户读、写、执行权限S_IRWXO00007其他用户执行权限S_IXOTH00001其他用户写权限S_IWOTH00002其他用户读权限S_IROTH00004组成员读、写、执权限S_IRWXG00070组成员执行权限S_IXGRP00010组成员写权限S_IWGRP00020组成员读权限S_IRGRP00040所有者读、写、执行权限S_IRWXU(00700)所有者执行权限
S_IXUSR(00100)所有者写权限
S_IWUSR(00200)所有者读权限S_IRUSR(00400)含义取值基本I/O系统调用28read()/write()系统调用read()功能从文件描述符读取数据头文件#include<unistd.h>函数原型ssize_tread(intfd,void*buf,size_tcount);返回值:读到的字节数,若已到文件尾为0,若出错为-1write()功能将数据写入文件描述符头文件#include<unistd.h>函数原型ssize_twrite(intfd,constvoid*buf,size_tcount);返回值:若成功为已写的字节数,若出错为-1基本I/O系统调用29close()系统调用功能关闭文件描述符头文件#include<unistd.h>函数原型intclose(intfd);成功:返回0失败:返回-1基本I/O系统调用30文件操作实例#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<fcntl.h>#include<string.h>intmain(){intfd;fd=open("./test.c",O_RDONLY);if(fd<0){ perror("openerror:"); printf("errnois:%d\n",errno);}else printf("openok\n");close(fd); return0;}基本I/O系统调用31文件操作示例/*arudimentaryexampleprogram*/#include<fcntl.h>main(){intfd,nread;charbuf[1024];/*openfile“data”forreading*/fd=open(“data”,O_RDONLY);/*readinthedata*/nread=read(fd,buf,1024);/*closethefile*/close(fd);}基本I/O系统调用32lseek()系统调用功能调节读写的偏移量头文件#include<sys/types.h>#include<unistd.h>函数原型off_tlseek(intfildes,off_toffset,intwhence);返回值成功时返回偏移量位置否则返回-1whence说明SEEK_SET:从文件头开始的偏移量SEEK_CUR:从当前位置开始加offset后的偏移值SEEK_END:从文件末开始加offset后的偏移值基本I/O系统调用33dup()系统调用功能复制文件描述符头文件#include<unistd.h>函数原型intdup(intoldfd);传给该函数一个现有描述符,返回一个新的描述符新描述符是传给它的描述符的拷贝,即两描述符共享同一数据结构如果对一个文件描述符执行lseek操作,得到的第一个文件的位置和第二个是一样的返回值成功时返回新文件描述符否则-1基本I/O系统调用34dup2()系统调用功能复制文件描述符头文件#include<unistd.h>函数原型intdup2(intoldfd,intnewfd);允许规定一个有效描述符(oldfd)和目标描述符(newfd)目标描述符将变成源描述符的复制品,即两个文件描述符指向同一文件,且是源描述符指向的文件返回值成功时返回新文件描述符否则-1基本I/O系统调用35dup()/dup2()系统调用示例#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<fcntl.h>#include<string.h>intmain(){intfd;fd=open("./test.c",O_RDWR|O_CREAT,S_IRWXU);if(fd<0){perror("open:");printf("errnois:%d\n",errno);}elseprintf("openok\n");基本I/O系统调用36dup()/dup2()系统调用示例intfdcopy;//fdcopy=dup(fd);dup2(fd,fdcopy);intwnum;wnum=write(fdcopy,"123456789",9);if(wnum!=9)perror("writefdcopy:");elseprintf("writeok\n");lseek(fd,0,SEEK_SET);charbuf[10];intrnum;rnum=read(fd,buf,9);printf("rnum:%d\n",rnum);基本I/O系统调用if(rnum!=9)perror("read:");elseprintf("readok,thestringis:%s\n",buf);close(fd);return0;}37fcntl()系统调用功能根据文件描述符来操作文件的特性头文件#include<unistd.h>#include<fcntl.h>函数原型intfcntl(intfd,intcmd);intfcntl(intfd,intcmd,longarg);intfcntl(intfd,intcmd,structflock*lock);参数说明fd:文件描述符cmd:操作命令arg:命令使用的参数lock:同上返回值若成功,则依赖于cmd若出错为-1基本I/O系统调用38fcntl()系统调用(续)cmd参数说明F_DUPFD:复制文件描述符FD_CLOEXEC:设置close-on-exec标志F_GETFD:读取文件描述符标志F_SETFD:设置文件描述符标志F_GETFL:读取文件状态标志F_SETFL:设置文件状态标志F_GETLK:获取记录锁F_SETLK:释放记录锁F_SETLKW:测试记录锁基本I/O系统调用39fcntl()系统调用示例intopenfd;char*ptr1="hello";char*ptr2="world";openfd=open("./fcntl.txt",O_CREAT|O_RDWR,S_IRWXU);if(openfd<0){perror("open:");printf("errnois:%d\n",errno);}elseprintf("openok\n");基本I/O系统调用
intwriteNum;writeNum=write(openfd,ptr1,strlen(ptr1));if(writeNum!=strlen(ptr1)){perror(“writeopenfd:");}elseprintf("writeok\n");intfcntlfd;fcntlfd=fcntl(openfd,F_DUPFD,0);printf("fcntlfd:%d\n",fcntlfd);writeNum=write(fcntlfd,ptr2,strlen(ptr2));40if(writeNum!=strlen(ptr2)){printf("writeerrno:%d\n",errno);perror(“writefcntlfd:");}elseprintf("writeok\n");lseek(openfd,0,SEEK_SET);intreadNum;charbuf[10];readNum=read(openfd,buf,10);printf("read:%s\n",buf);close(openfd);close(fcntlfd);return0;41文件系统练习一编写代码,完成以下功能:1.创建文件file1,写入字符串“abcdefghijklmn”;2.创建文件file2,写入字符串“ABCDEFGHIJKLMN”;3.读取file1中的内容,写入file2,使file2中的字符串内容为“abcdefghijklmnABCDEFGHIJKLMN”42文件操作练习二编写代码,完成以下功能:1.创建新文件,该文件具有用户读写权限。2.采用dup/dup2/fcntl复制一个新的文件描述符,通过新文件描述符向文件写入“class_name”字符串;3.通过原有的文件描述符读取文件中的内容,并且打印显示;4344主要内容文件系统概述系统调用与库函数基本I/O系统调用文件属性及目录相关系统调用标准I/O库高级I/O库45structstat结构定义structstat{mode_tst_mode;/*filetype&mode*/ino_tst_ino;/*inodenumber(serialnumber)*/dev_tst_rdev;/*devicenumber(filesystem)*/nlink_tst_nlink;/*linkcount*/uid_tst_uid;/*userIDofowner*/gid_tst_gid;/*groupIDofowner*/off_tst_size;/*sizeoffile,inbytes*/time_tst_atime;/*timeoflastaccess*/time_tst_mtime;/*timeoflastmodification*/time_tst_ctime;/*timeoflastfilestatuschange*/longst_blksize;/*OptimalblocksizeforI/O*/longst_blocks;/*number512-byteblocksallocated*/};文件属性及目录相关系统调用46stat()/fstat()/lstat()系统调用功能获取文件状态头文件#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>函数原型intstat(constchar*file_name,structstat*buf);intfstat(intfiledes,structstat*buf);intlstat(constchar*file_name,structstat*buf);与stat()差别:为符号连接时,lstat()返回连接自身状态返回值成功时返回0否则-1文件属性及目录相关系统调用47测试文件类型的宏定义位置<sys/stat.h>socketS_ISSOCK()符号链接S_ISLNK()fifoS_ISFIFO()块文件S_ISBLK()字符文件S_ISCHAR()目录S_ISDIR()普通文件S_ISREG()文件类型宏文件属性及目录相关系统调用48文件类型测试示例#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<fcntl.h>#include<string.h>#include<sys/stat.h>intmain(intargc,char*argv[]){structstatstatBuf;char*ptr;文件属性及目录相关系统调用49文件权限其他用户读、写、执行S_IRWXO(00007)其他用户执行S_IXOTH(00001)其他用户写S_IWOTH(00002)其他用户读S_IROTH(00004)组用户读、写、执行S_IRWXG(00070)组用户执行S_IXGRP(00010)组用户写S_IWGRP(00020)组用户读S_IRGRP(00040)所有者读、写执行S_IRWXU(00700)所有者执行
S_IXUSR(00100)所有者写
S_IWUSR(00200)所有者读S_IRUSR(00400)含义
st_mode屏蔽保存文本位
S_ISVTX(01000)在组ID设置执行权限
S_ISGID(02000)在用户ID设置执行权限S_ISUID(04000)文件属性及目录相关系统调用50文件权限示例if(buf.st_mode&S_IRUSR) printf(“readablebyowner”);else printf(“unreadablebyowner”);文件属性及目录相关系统调用51access()系统调用功能按实际用户ID和实际组ID测试文件存取权限头文件#include<unistd.h>函数原型intaccess(constchar*pathname,intmode);返回值成功时返回0否则-1mode参数说明F_OK值为0,判断文件是否存在R_OK值为4,判断对文件是否有读权限W_OK值为2,判断对文件是否有写权限X_OK值为1,判断对文件是否有读写权限(R_OK|W_OK|X_OK:可以同时使用)文件属性及目录相关系统调用52access()系统调用示例if(argc<2){printf("twoormoreperemeters;\n");return0;}for(inti=1;i<argc;i++){if(access(argv[i],R_OK)<0)perror("accessR_OK:");elseprintf("usercanread%s\n",argv[i]);}return0;文件属性及目录相关系统调用53umask()系统调用功能为进程设置文件存取权限屏蔽字.头文件#include<sys/types.h>#include<sys/stat.h>函数原型mode_tumask(mode_tmask);文件属性及目录相关系统调用54参数mode与umaskumask文件保护机制新文件的初始访问模式mode&~umask文件属性及目录相关系统调用55umask()系统调用示例文件属性及目录相关系统调用56chmod()/fchmod()系统调用功能更改文件权限头文件#include<sys/types.h>#include<sys/stat.h>函数原型intchmod(constchar*path,mode_tmode);intfchmod(intfildes,mode_tmode);返回值成功时返回0失败返回-1文件属性及目录相关系统调用57chmod()/fchmod()系统调用示例文件属性及目录相关系统调用S_ISGID对应SETGID位S_ISUID对应SETUID位设置该位置生效58chown()/fchown()/lchown()系统调用功能变更文件宿主头文件#include<sys/types.h>#include<unistd.h>函数原型intchown(constchar*path,uid_towner,gid_tgroup);intfchown(intfd,uid_towner,gid_tgroup);intlchown(constchar*path,uid_towner,gid_tgroup);若path为符号连接,lchown()改变连接本身的所有者或组,chown()则改变连接所指向文件的所有者或组返回值成功时返回0失败返回-1文件属性及目录相关系统调用59link()/unlink()系统调用功能创建/删除一个硬链接头文件#include<unistd.h>函数原型intlink(constchar*oldpath,constchar*newpath);intunlink(constchar*pathname);删除一个文件的目录项并减少它的链接数返回值成功时返回0失败返回-1文件属性及目录相关系统调用60link()/unlink()系统调用示例#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>intmain(void){intfd;if((fd=open("tempfile",O_RDWR|O_CREAT))<0){perror("open");exit(1);}文件属性及目录相关系统调用structstatstatBuf;fstat(fd,&statBuf);printf("tempfilelinknum:%ld\n",statBuf.st_nlink);sleep(5);if(unlink("tempfile")<0){perror("unlink");exit(1);}fstat(fd,&statBuf);printf("afterunlink,tempfilelinknum:%ld\n",statBuf.st_nlink);printf("fileunlinked\n");exit(0);}6162symlink()/readlink()系统调用头文件#include<unistd.h>函数原型intsymlink(constchar*oldpath,constchar*newpath);功能:用来创建符号链接文件。返回值成功时返回0否则-1intreadlink(constchar*path,char*buf,size_tbufsiz);功能:readlink函数用来读取链接文件本身的内容(也就是符号链接指向的文件的文件名)。返回值成功时返回放置在buffer中的字符数否则-1文件属性及目录相关系统调用intmain(){charbuf[256];intreadNum;readNum=readlink("smain.c",buf,256);printf("buf:%s\n",buf);printf("readnum:%d\n",readNum);return0;}63文件系统练习三编写程序实现以下功能:1.输入文件名称,能够判断文件类型,判断实际用户对该文件具有哪些存取权限;2.要求打印出文件类型信息,inode节点编号,链接数目,用户id,组id,文件大小信息;3.修改文件的权限为当前用户读写,组内用户读写,组外用户无权限。64文件系统练习四编写程序实现以下功能:1.新建文件,设置文件权限屏蔽字为0;2.建立该文件的硬链接文件,打印硬链接文件的inode节点号和文件大小;3.建立该文件的软链接文件,打印软链接文件的inode节点号和文件大小;打印软链接文件中的内容;4.打印源文件的inode节点号,文件大小和链接数目;5.调用unlink对源文件进行操作,打印源文件链接数目;6566目录处理相关系统调用创建/删除目录mkdir()/rmdir()更改/获取目录chdir()/fchdir(),getcwd()读取目录信息opendir()/closedir()readdir()telldir()seekdir()文件属性及目录相关系统调用67mkdir()/rmdir()系统调用功能创建/删除一个空目录头文件#include<sys/stat.h>#include<sys/types.h>函数原型intmkdir(constchar*pathname,mode_tmode);intrmdir(constchar*pathname);返回值成功时返回0失败时返回-1文件属性及目录相关系统调用intmain(){if(mkdir("/root/docu/test/test/mkdirtest",0444)<0)perror("mkdirerror:");sleep(10);if(rmdir("/root/docu/test/test/mkdirtest")<0)perror("rmdir:");return0;}6869chdir()/fchdir()系统调用功能更改工作目录头文件#include<unistd.h>函数原型intchdir(constchar*path);intfchdir(intfd);返回值成功时返回0失败时返回-1说明当前工作目录是进程的属性,所以该函数只影响调用chdir的进程本身文件属性及目录相关系统调用70getcwd()系统调用功能获得当前工作目录的绝对路径头文件#include<unistd.h>函数原型char*getcwd(char*buf,size_tsize);返回值成功时返回buf出错则为NULL注意1、在调用此函数时,buf所指的内存空间要足够大。若工作目录绝对路径的字符串长度超过参数size大小,则返回NULL,errno的值则为ERANGE。
2、倘若参数buf为NULL,getcwd()会依参数size的大小自动配置内存(使用malloc()),如果参数size也为0,则getcwd()会依工作目录绝对路径的字符串长度来决定所配置的内存大小,进程可以在使用完次字符串后利用free()来释放此空间。文件属性及目录相关系统调用#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
main()
{
intfd;
printf("currentworkingdirectory:%s\n",getcwd(NULL,NULL));
fd=open("/tmp",O_RDONLY);
fchdir(fd);
printf("currentworkingdirectory:%s\n",getcwd(NULL,NULL));
close(fd);return0;
}
71#include<stdio.h>#include<stdlib.h>#definesize40intmain(intargc,char*argv[]){
char*ptr=(char*)malloc(size*sizeof(char));getcwd(ptr,size);printf("workdiris:%s\n",ptr);free(ptr); return0;}7273读取目录信息数据结构DIR,structdirent基本操作opendir()/closedir()readdir()telldir()seekdir()文件属性及目录相关系统调用74基本数据结构DIR目录流对象头文件<dirent.h>定义形式typedefstruct_dirstreamDIR;structdirent目录项头文件<dirent.h>定义ino_td_ino;/*inode号*/chard_name[NAME_MAX+1];/*文件名*/文件属性及目录相关系统调用75目录基本操作功能打开、关闭、读、定位头文件#include<sys/types.h>#include<dirent.h>函数原型DIR*opendir(constchar*name);intclosedir(DIR*dir);structdirent*readdir(DIR*dir);off_ttelldir(DIR*dir);//获取目录流读取位置voidseekdir(DIR*dir,off_toffset);文件属性及目录相关系统调用struct
dirent
结构体struct
dirent
{
long
d_ino;
/*
inode
number
索引节点号
*/
off_t
d_off;
/*
offset
to
this
dirent
在目录文件中的偏移
*/
unsigned
short
d_reclen;
/*
length
of
this
d_name
文件名长
*/
unsigned
char
d_type;
/*
the
type
of
d_name
文件类型
*/
char
d_name
[NAME_MAX+1];
/*
file
name
(null-terminated)
文件名,最长255字符
*/
}
7677目录扫描程序示例DIR*dir;structdirent*dirp;structstatstatbuf;if(argc<2){printf("twoormoreparameters\n");return-1;}for(inti=1;i<argc;i++){if(lstat(argv[i],&statbuf)<0){perror("lsata:");}文件属性及目录相关系统调用78目录扫描程序示例if(S_ISDIR(statbuf.st_mode)){dir=opendir(argv[i]);if(dir){while((dirp=readdir(dir))!=NULL){if(dirp->d_name[0]=='.')continue;printf("inode=%ld\n",dirp->d_ino);printf("filename:%s\n",dirp->d_name);}}elseperror("opendirerror:");closedir(dir);}文件属性及目录相关系统调用else{printf("isnotdirectory\n");}}return0;文件系统练习五1.新建/home/user目录;2.把当前工作路径移至/home/user目录;3.打印当前工作路径;79文件系统练习六编写程序完成以下功能:1.递归遍历/home目录,打印出所有文件和子目录名称及节点号。2.判断文件类型,如果是子目录,继续进行递归遍历,直到遍历完所有子目录为止。8081主要内容文件系统概述系统调用与库函数基本I/O系统调用文件属性及目录相关系统调用标准I/O库高级I/O库82文件流缓存I/OStream及“FILE”结构FILE*fp;预定义指针externFILE*stdin;externFILE*stdout;externFILE*stderr;标准I/O库typedefstruct{intcnt;//余下的字符数
char*ptr;//下一个字符的位置
char*base;//缓冲区的地址
intflag;//存取方式
intfd;//文件描述符}FILE;83FILE结构定义缓冲文件系统为每个正在被使用的文件在内存开辟文件信息区文件信息用FILE结构体描述标准I/O库磁盘文件输出文件缓冲区输入文件缓冲区程序数据区a缓冲文件系统fclose不关闭文件可能会丢失数据84文件类型指针指针变量说明
FILE*fp;用法文件打开时,系统自动建立文件结构体返回指向它的指针,程序通过这个指针获得文件信息,访问文件文件关闭后,文件结构体被释放文件名文件使用方式文件类型指针C程序操作系统磁盘标准I/O库85标准I/O函数文件流的打开/关闭文件流的读/写每次一个字符的I/O每次一行的I/O直接I/O(二进制I/O)格式化I/O文件流的定位文件流的fflush标准I/O库86fopen()函数功能打开文件流头文件#include<stdio.h>函数原型FILE*fopen(constchar*filename,constchar*mode);mode参数说明“r”:
以读方式打开文本文件“w”:
以写方式创建一个文件,覆盖老文件“a”:
以追加方式打开文件“r+”:
以读写方式打开一个现存文件“w+”:以读写方式打开一个文件若不存在,将创建之若存在,将覆盖原文件“a+”:
以读及追加方式打开文件,若不存在,将创建之“b”:以二进制模式打开文件“t”:以文本模式打开文件标准I/O库87fclose()函数功能关闭文件流头文件#include<stdio.h>函数原型intfclose(FILE*stream);返回值成功时返回0否则-1标准I/O库88输入字符头文件#include<stdio.h>函数原型intfgetc(FILE*fp);从文件流中读取下一个字节,并作为字符返回到达文件尾或出现错误时,返回EOFintgetc(FILE*fp);与fgetc()功能类似,但可实现成一个宏intgetchar(void);相当于getc(stdin)标准I/O库89输出字符头文件#include<stdio.h>函数原型intfputc(intc,FILE*fp);向输出文件流写入一个字符intputc(intc,FILE*fp);intputchar(intc);相当于putc(c,stdout)返回值成功时返回写入的字符ASC码值否则返回-1标准I/O库90字符读写操作示例1标准I/O库91字符读写操作示例2文件拷贝从键盘输入字符,逐个显示到屏幕上并存到磁盘文件中,直到输入‘#“为止读文本文件内容,并显示feof函数原型:intfeof(FILE*fp)功能:判断文件是否结束返值:文件结束,返回真(非0);文件未结束,返回0#include<stdio.h>main(){FILE*in,*out;charinfile[10],charoutfile[10];scanf("%s",infile);scanf("%s",outfile);if((in=fopen(infile,"r"))==NULL){
puts("Cannotopeninfile.\n");
exit(0);}if((out=fopen(outfile,"w"))==NULL){puts("Cannotopenoutfile.\n");
exit(0);}
while(!feof(in))fputc(fgetc(in),out);
fclose(in);
fclose(out);}#include<stdio.h>main(){FILE*fp;charch;if((fp=fopen(“out.txt”,"w"))==NULL){printf("cannotopenfile\n"); exit(0);}printf("Pleaseinputstring:");ch=getchar();while(ch!='#'){putchar(ch);
fputc(ch,fp);ch=getchar();}fclose(fp);}#include<stdio.h>main(){FILE*fp;charch;if((fp=fopen(“out.txt”,”r"))==NULL){printf("cannotopenfile\n");exit(0);}while((ch=fgetc(fp))!=EOF)putchar(ch);fclose(fp);}<>标准I/O库
判断文件是否结束
while(!feof(fp)){ch=fgetc(fp);……..}while(feof(fp)==0)
{ch=fgetc(fp);
……..
}92输入一行字符串头文件#include<stdio.h>函数原型char*fgets(char*s,intsize,FILE*stream);最多读取size-1个字符,并保存在s中遇到EOF或者新行时读操作结束‘\0’保存在s的末尾char*gets(char*s);类似fgets(),但从标准输入读取数据并丢弃遇到的换行符号返回值成功返回指向字符串s的指针失败返回NULL标准I/O库93输出一行字符串头文件#include<stdio.h>函数原型intfputs(constchar*s,FILE*stream);intputs(constchar*s);返回值如果写入成功,则返回非0(不是写入的字节数,仅仅是个非零值),此时编译器默认为返回1。如果写入错误,则返回EOF。注意:puts会自动在输入的字符串末尾加入回车符标准I/O库94字符串读写操作示例2#include<stdio.h>main(){FILE*fp;charstring[81];if((fp=fopen("file.txt","w"))==NULL){printf("cann'topenfile");exit(0);}while(strlen(gets(string))>0){
fputs(string,fp);
fputs("\n",fp);}标准I/O库fclose(fp);if((fp=fopen("file.txt","r"))==NULL){printf("cann'topenfile");exit(0);}while(fgets(string,81,fp)!=NULL)
puts(string);fclose(fp);}95格式化I/O获取外部数据函数头文件#include<stdio.h>函数原型intfprintf(FILE*fp,constchar*format,…)intfscanf(FILE*fp,constchar*format,…)功能按格式对文件进行I/O操作返值成功,返回I/O的个数出错或文件尾,返回EOF例fprintf(fp,“%d,%6.2f”,i,t);//将i和t按%d,%6.2f格式输出到fp文件
fscanf(fp,“%d,%f”,&i,&t);//若文件中有3,4.5,则将3送入i,4.5送入tprintf(“%d,%6.2f”,i,t);//将i和t按%d,%6.2f格式输出到屏幕
scanf(“%d,%f”,&i,&t);//若键盘输入为3,4.5,则将3送入i,4.5送入t标准I/O库96格式化I/O用法示例取指定长度的字符串#include<stdio.h>main(){chars[80],c[80];inta,b;FILE*fp;if((fp=fopen("test","w"))==NULL){
puts("can'topenfile");exit();}标准I/O库scanf("%s%d",s,&a);
fprintf(fp,"%s%d",s,a);
fclose(fp);if((fp=fopen("test","r"))==NULL){puts(“can‘topenfile”);exit();}fscanf(fp,"%s%d",c,&b);printf("%s%d",c,b);fclose(fp);}97流文件的输入/输出功能读/写数据块头文件#include<stdio.h>函数原型size_tfread(void*buffer,size_tsize,size_tcount,FILE*fp);sizefwrite(constvoid*buffer,size_tsize,size_tcount,FILE*fp);参数说明buffer:指向要输入/输出数据块的首地址的指针size:每个要读/写的数据块的大小(字节数)count:要读/写的数据块的个数fp:要读/写的文件指针fread与fwrite主要用于二进制文件的输入/输出返值成功,返回读/写的块数出错或文件尾,返回0标准I/O库98流文件的输入/输出示例1例floatf[2];FILE*fp;fp=fopen(“aa.dat”,“rb”);
fread(f,4,2,fp);for(i=0;i<2;i++){
fread(&f[i],4,1,fp);
}例structstudent{intnum;charname[20];charsex;intage;floatscore[3];}stud[10];for(i=0;i<10;i++)
fread(&stud[i],sizeof(structstudent),1,fp);标准I/O库99流文件的输入/输出示例2#include<stdio.h>#defineSIZE4structstudent_type{charname[10];intnum;intage;charaddr[15];}stud[SIZE];main(){inti;for(i=0;i<SIZE;i++) scanf("%s%d%d%s",stud[i].name,&stud[i].num, &stud[i].age,stud[i].addr);
save();display();}voidsave(){FILE*fp;inti;if((fp=fopen("d:\\fengyi\\exe\\stu_dat","wb"))==NULL){printf("cannotopenfile\n");return;}for(i=0;i<SIZE;i++)if(fwrite(&stud[i],sizeof(structstudent_type),1,fp)!=1) printf("filewriteerror\n");
fclose(fp);}voiddisplay(){FILE*fp;inti;if((fp=fopen("d:\\fengyi\\exe\\stu_dat","rb"))==NULL){printf("cannotopenfile\n");return;}for(i=0;i<SIZE;i++){
fread(&stud[i],sizeof(structstudent_type),1,fp);printf("%-10s%4d%4d%-15s\n",stud[i].name,stud[i].num,stud[i].age,stud[i].addr);}
fclose(fp);}标准I/O库100文件定位文件的定位文件位置指针-----指向当前读写位置的指针读写方式顺序读写:每次均以上次读或写入后的下一位置作为本次读或写的起点随机读写:位置指针按需要移动到任意位置rewind函数函数原型voidrewind(FILE*fp)功能重置文件位置指针到文件开头返值无标准I/O库101文件定位示例对一个磁盘文件进行显示和复制两次操作#include<stdio.h>main(){FILE*fp1,*fp2;fp1=fopen("d:\\fengyi\\bkc\\ch12_4.c","r");fp2=fopen("d:\\fengyi\\bkc\\ch12_41.c","w");while(!feof(fp1))putchar(getc(fp1));
rewind(fp1);while(!feof(fp1))putc(getc(fp1),fp2);
fclose(fp1);fclose(fp2);}标准I/O库102文件定位fseek函数函数原型:intfseek(FILE*fp,longoffset,intwhence)功能:改变文件位置指针的位置返值:成功,返回0;失败,返回非0值ftell函数函数原型longftell(FILE*fp)功能:返回位置指针当前位置(用相对文件开头的位移量表示)返值:成功,返回当前位置指针位置;失败,返回-1L文件指针位移量(以起始点为基点,移动的字节数)>0
向后移动<0
向前移动起始点文件开始
SEEK_SET0文件当前位置
SEEK_CUR1文件末尾
SEEK_END2例fseek(fp,100,0);fseek(fp,50,1);fseek(fp,-10,2);起始点文件开始
SEEK_SET0文件当前位置
SEEK_CUR1文件末尾
SEEK_END2标准I/O库103fseek函数示例main(){inti;FILE*fp;if((fp=fopen("studat","rb"))==NULL){printf("can'topenfile\n");exit(0);}scanf(“%d”,&i);
fseek(fp,i*sizeof(structstudent_type),0);
fread(&stud,sizeof(structstudent_type),1,fp);printf("%s%d%d%s\n",,stud.num,stud.age,stud.addr);
fclose(fp);}#include<stdio.h>structstudent_type{intnum;charname[10];intage;charaddr[15];}stud;标准I/O库104fflush()函数功能刷新文件流,把流里的数据立刻写入文件头文件#include<stdio.h>函数原型intfflush(FILE*stream);磁盘文件输出文件缓冲区输入文件缓冲区程序数据区a缓冲文件系统:fflush()不关闭文件可能会丢失数据标准I/O库105出错处理函数ferror()函数函数原型:intferror(FILE*fp)功能:测试文件流是否出现错误,比如以写的方式打开文件,但是对文件进行读操作。返回值:未出错,0;出错,非0说明ferror是为了增强代码的健壮性加入的检验性程序,避免操作文件出现错误。标准I/O库clearerr()函数函数原型:
voidclearerr(FILE*fp)功能:清除文件流的错误标志位。返值:无说明clearerr()和ferror()配对使用,如果ferror(fp)发现错误,返回非0值,则错误标志一直保留,影响后续对文件的操作。需要调用clearerr()对该文件流中的错误标志位进行清楚操作。或者调用rewind()函数或任何其它一个输入输出函数也能完成类似的功能。107出错处理函数示例#include<stdio.h>intmain(void){FILE*stream;stream=fopen("DUMMY.FIL","w");getc(stream);if(ferror(stream)){printf("ErrorreadingfromDUMMY.FIL\n");clearerr(stream);}if(!ferror(stream))printf("Errorindicatorcleared!");
fclose(stream);return0;}标准I/O库108文件流缓存操作相关函数头文件#include<stdio.h>函数原型voidsetbuf(FILE*stream,char*buf);buf指出的缓冲区长度由头文件stdio.h中定义的宏BUFSIZE的值决定,缺省值为512字节。当选定buf为空时,setbuf函数将使的文件I/O不带缓冲。intsetvbuf(FILE*stream,char*buf,intmode,size_tsize);setvbuf函数,可以由malloc函数来分配缓冲区。参数size指明了缓冲区的长度(必须大于0),而参数mode则表示了缓冲的类型,其值可以取如下值:
_IOFBF文件全部缓冲,即缓冲区装满后,才能对文件读写
_IOLBF文件行缓冲,即缓冲区接收到一个换行符时,才能对文件读写
_IONBF文件不缓冲,此时忽略buf,size的值,直接读写文件,不再经过文件缓冲区缓冲标准I/O库109文件流缓存操
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 大连商务职业学院《合唱与指挥A》2023-2024学年第二学期期末试卷
- 山西省长治市长子县2025届小升初数学高频考点模拟卷含解析
- 中医操作在社区中的运用
- 淤泥晾晒施工方案
- 家具商场物业工作总结
- 教育学试讲模板幼儿园
- 工程项目管理分析报告
- 四川省卫生类事业单位公开招聘(中药专业)近年考试真题库及答案
- 工作总结数字量化
- 市场调研分析培训班
- 2025山东淄博高新国资本投资限公司选聘国员工11人高频重点提升(共500题)附带答案详解
- 2025中国铁塔集团河北分公司招聘9人高频重点提升(共500题)附带答案详解
- 巴蜀文化知到智慧树章节测试课后答案2024年秋四川大学
- 编外聘人员考试题库
- 【MOOC】中国近现代史纲要-武汉大学 中国大学慕课MOOC答案
- TSG11-2020锅炉安全技术规程(现行)
- 酒吧夜店数字化转型
- 矿山应急救援知识
- 歌曲《wake》中英文歌词对照
- 养老院安全隐患排查和整改制度
- 小学语文整本书阅读《小彗星旅行记》 导读课件
评论
0/150
提交评论