UNIXLinux环境高级编程

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

低级文件I/O系统调用•open()read()write()•lseek()dup()dup2()•fcntl()lockf()flock()•ioctl()close()文件描述•当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read、write、lseek和close等。•按照惯例,UNIXshell使文件描述符:–0-stdin1-stdout2-stderr•在POSIX.1应用程序中,标准I/O描述符被定义为:–0-STDIN_FILENO;1-STDOUT_FILENO;2-STDERR_FILENO–这些常数都定义在头文件unistd.h中。•文件描述符的范围是0~OPEN_MAX。早期的UNIX版本采用的上限值是19(即20),现在很多系统则将其增加至256且可以以内核参数的办法设置,比方说1024。原始系统数据类型•在UNIX/Linux的开发过程中用到的以_t结尾的数据为系统原始数据。•系统原始数据在头文件sys/types.h中被定义。出错处理•UNIX函数出错时,往常返回一个负值,而且整型变量errno通常设置为具有特定信息的一个值。例如,open函数如成功执行则返回一个非负文件描述符,如出错则返回-1。•在open出错时,有大约15种不同的errno值。–某些函数并不返回负值而是使用另一种约定。例如,返回一个指向对象的指针的大多数函数,在出错时,将返回一个null指针(NULL)。•文件errno.h中定义了变量errno以及可以赋与它的各种常数。这些常数都以E开头。•在Linux系统中,errno定义在头文件/usr/include/asm/errno.h,多达124条。errno•POSIX定义errno为:externinterrno;•对于errno应当知道两条规则:–1:如果没有出错,则其值不会被一个例程清除。因此,仅当函数的返回值指明出错时,才检验其值。–2:任一函数都不会将errno值设置为0,在errno.h中定义的所有常数都不为0。错误处理的标准函数•strerror():–功能:以字符串方式打印错误信息。–用法:•#includestring.h•char*strerror(interrnum);–返回:指向消息字符串的指针。•perror()–功能:在标准错误上产生一条基于其参数串和errno的当前值出错消息。–用法:•#includestdio.h•voidperror(constchar*msg);–输出:首先输出由msg指向的字符串,然后是一个冒号,一个空格,然后是对应于errno值的出错信息,然后是一个新行符。处理错误的示例1#includestdio.h#includeerrno.hmain(intargc,char*argv[]){fprintf(stderr,EACCES=%d:%s\n,EACCES,strerror(EACCES));errno=ENOENT;perror(argv[0]);}结果:假设,编译后生成a.out,则输出为:EACCES=13:Permissiondenied./a.out:Nosuchfileordirectory处理错误的示例2#includeerror.h#includefcntl.hmain(intargc,char*argv[]){inti,fd;for(i=1;iargc;i++){if((fd=open(argv[i],O_RDWR))==-1)perror(argv[i]);elseclose(fd);}}open•功能:–打开或创建一个文件,并返回一个文件描述符。•用方:–#includesys/types.h–#includesys/stat.h–#includefcntl.h–intopen(constchar*name,intoflag);–intopen(constchar*ame,intoflag,mode_tmode);•返回值:–成功时为文件描述符,出错则为-1。–出错时errno被设置。open的参数•pathname是要打开或创建的文件的名字。•oflag参数可用来说明此函数的多个选择项。用下列一个或多个常数进行或运算构成oflag参数(在fcntl.h中):•O_RDONLY:只读打开。•O_WRONLY:只写打开。•O_RDWR:读写打开•O_APPEND:追加方式。•O_CREAT:若不存在则创建它。需同时使用第三个参数mode。•O_EXCL:如果同时指定了O_CREAT,而文件已经存在,则出错。这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作。•O_TRUNC:果此文件存在,则将其长度截短为0。•O_NOCTTY:如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。•O_NONBLOCK:如果pathname指的是特殊文件,此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式。creat•功能:创建一个新文件•用法:–#includesys/types.h–#includesys/stat.h–#includefcntl.h–intcreat(constchar*name,mode_tmode);•返回:–成功为只写打开的文件描述符;出错为-1。–出错时errno被设置。•注意:此函数等效于:–open(name,O_WRONLY|O_CREAT|O_TRUNC,mode);creat和open中可使用权限S_IRWXU用户主的读写和执行权S_IRUSR用户读S_IWUSRS_IXUSR用户写用户执行S_IRWXG组的读写执行S_IRGRP组读S_IWGRP组写S_IXGRP组执行S_IRWXO其它人的读写执行S_IROTH其它人读S_IWOTH其它人写S_IXOTH其它执行read•功能:从描述符为fd的文件读信息。•用法:–#includeunistd.h–ssize_tread(intfd,void*buff,size_tnbytes);•返回:–读到的字节数,若已到文件尾为0,若出错为-1。–出错时errno被设置。•在UNIX/Linux可重定义为:–intread(intfd,char*buff,unsignednbytes);write•功能:向已打开的文件写数据。•用法:–#includeunistd.h–ssize_twrite(intfd,constvoid*buff,size_tnbytes);•返回值:–若成功为已写入的字节数;出错为-1。–出错时errno被设置。•在UNIX/Linux可重定义为:–intwrite(intfd,char*buff,unsignednbytes);文件位置指针•文件位置指针:每个打开文件都有一个与其相关联的“当前偏移量”。是从文件开始处计算的字节数。通常,读、写操作都从当前文件位置处开始,并使位移量增加所读或写的字节数。•按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该偏移量被设置为0,即指向文件的开始处。•文件位置指针可以通过系统调用lseek来移动。lseek•功能:显式地定位一个打开文件的位置指针。•用法:–#includesys/types.h–#includeunistd.h–off_tlseek(intfd,off_toffset,intwhence);•返回值:若成功为新的文件位移,若出错为-1。出错时errno被设置。•说明:对参数offset的解释与参数whence的值有关:–whence=SEEK_SET(=0),从文件开始。–whence=SEEK_CUR(=1),从当前位置,offset可正可负。–whence=SEEK_END(=2),从文件末尾,offset可为正或负。•例:求文件的当前位置指针:–off_tcurrpos;currpos=lseek(fd,0,SEEK_CUR);–这种方法也可用来确定所涉及的文件是否可以设置位移量。如果文件描述符引用的是一个管道或FIFO,则lseek返回-1,并将errno设置为EPIPE。文件的共享(三种数据结构)•(1)v节点解构,即虚拟文件系统i节点结构。–指向磁盘i节点的指针和相关信息。•(2)系统文件表,是内核为所有打开文件维持一张文件表。–文件状态标志(读、写、同步、非阻塞等)。–当前文件指针。–指向v节点解构的指针。•(3)进程文件表,每个进程在执行过程中都有一个记录它自己打开的文件描述符表。–文件描述符标志。–指向系统打开文件表一个表项的指针。三种数据结构之间的关系进程间文件共享情况dup与dup2•功能:复制已有的文件描述符•用法:–#includeunistd.h–intdup(intori_fd);–intdup2(intori_fd,intnew_fd);•返回值:–若成功返回新的描述符,失败时返回-1;–出错时errno被设置。•说明:–新描述符与原来的描述具有相同的文件表,共享同一个文件标志;–使用dup2时,若new_fd为已打开者,则先关闭之。进程内文件共享情况文件的互斥•伴随文件的共享而来的是文件的互斥访问。这表现为同一文件或其中的一部分不允许两进程同时访问,若一个文件的某一部分存在被某一进程以写方式访问,另一进程也要访问同一个地方则它必须等待。实现文件互斥访问的办法是以互斥方式打开文件或文件上锁。•文件的互斥打开,可以在打开文件是使用O_EXCL参数。文件上锁可以使用flock()系统调用。flock()•功能:为一个打开的文件描述符上锁或解锁•用法:–#includesys/file.h–intflock(intfd,intop);•参数:–fd为已经打开的文件描述符–op为对fd的操作方式:•LOCK_SH:为文件fd上一个共享锁,在给定时间内可由多个进程共享此文件锁;•LOCK_EX:为文件fd加一个排它锁,在给定时刻只能有一个进程使用使用此文件锁;•LOCK_UN:去除文件fd上文件锁。•返回值:成功时返回0,否则返回-1,同时errno被设置。•说明:–由flock()创建的文件锁,与打开的文件fd相关联,且同一个文件不能同时具有共享锁和排它锁。这意味着如果一个描述符是由dup()或dup2()复制的,则它们拥有相同的文件锁。如果一个文件已经被一个进程上一个非“兼容”锁,当另一个进程也要为此文件加锁时可能被阻塞。lockf•功能–用于对一个打开的文件的部分进行加锁,实现进程间对此部分的互斥访问。•用法–#includesys/file.h–intlockf(intfd,intcmd,off_tlen);•返回值–若成功返回0,否则返回-1,并设置errno。参数•fd是以写方式打开的文件描述符;•cmd是锁定方式:–F_ULOCK(=0):解锁。–F_LOCK(=1):加锁。若要锁的部分的局部已经被其它进程锁定,则lock()被阻塞。在同一进程中,若上锁部分重叠,则上锁后,原先锁定部分和本次锁定部分合并。锁定部分当调用lockf()释放或进程关闭文件时解锁。这种锁不会被子进程继承。–F_TLOCK(=2):作用与F_LOCK同但不会被阻塞,若未上锁则加锁,若已经上锁则返回-1.–F_TEST(=3):测试是否上锁,若未上锁返回0,若已经上锁则返回-1。–len是要锁定的文件长度。•设文件位置指针为pos,则当len0时,锁定长度为pos~pos-1;若len0,则锁定长度为pos-len~pos-1;若len=0,则锁定长度为从pos开始到文件结束的所有部分。fcntl•功能:控制和改变已经打开文件的属性。•用法:–#includesys/types.h–#includeunistd.h–#includefcntl.h

1 / 41
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功