1linux系统调用和文件IO(ppt).pdf
文件操作主讲人主讲人主讲人主讲人:李奎李奎李奎李奎本章学习目标本章学习目标本章学习目标本章学习目标 文件操作文件操作文件操作文件操作在在在在linuxlinuxlinuxlinux系统编程中系统编程中系统编程中系统编程中,通过通过通过通过linuxlinuxlinuxlinux系统调用系统调用系统调用系统调用操作文件操作文件操作文件操作文件,完成完成完成完成本章学习应该能够通过本章学习应该能够通过本章学习应该能够通过本章学习应该能够通过linuxlinuxlinuxlinux系统调用系统调用系统调用系统调用操作文件以下部分操作文件以下部分操作文件以下部分操作文件以下部分:创建文件创建文件创建文件创建文件 读和写文件读和写文件读和写文件读和写文件 更新文件内容更新文件内容更新文件内容更新文件内容文件操作理论及原理介绍文件操作理论及原理介绍文件操作理论及原理介绍文件操作理论及原理介绍LinuxLinuxLinuxLinux系统调用系统调用系统调用系统调用所谓系统调用是操作系统提供给用户程序的一组所谓系统调用是操作系统提供给用户程序的一组所谓系统调用是操作系统提供给用户程序的一组所谓系统调用是操作系统提供给用户程序的一组特殊特殊特殊特殊接口接口接口接口,用户程序可以通过这组用户程序可以通过这组用户程序可以通过这组用户程序可以通过这组特殊特殊特殊特殊接口来获得操作系接口来获得操作系接口来获得操作系接口来获得操作系统内核提供的特殊服务统内核提供的特殊服务统内核提供的特殊服务统内核提供的特殊服务在在在在linuxlinuxlinuxlinux中用户程序不能直接访问中用户程序不能直接访问中用户程序不能直接访问中用户程序不能直接访问内核提供的服务内核提供的服务内核提供的服务内核提供的服务,为了更好的保护内核空间为了更好的保护内核空间为了更好的保护内核空间为了更好的保护内核空间,将程序的运将程序的运将程序的运将程序的运行空间分为内核空间和用户空间行空间分为内核空间和用户空间行空间分为内核空间和用户空间行空间分为内核空间和用户空间,它们运行在不同的级别它们运行在不同的级别它们运行在不同的级别它们运行在不同的级别上上上上,在逻辑上是相互隔离的在逻辑上是相互隔离的在逻辑上是相互隔离的在逻辑上是相互隔离的用户程序接口用户程序接口用户程序接口用户程序接口(APIAPIAPIAPI)在在在在linuxlinuxlinuxlinux中用户编程接口中用户编程接口中用户编程接口中用户编程接口(APIAPIAPIAPI)遵循了在遵循了在遵循了在遵循了在UNIXUNIXUNIXUNIX中最流行的中最流行的中最流行的中最流行的应用编程界面标准应用编程界面标准应用编程界面标准应用编程界面标准POSIXPOSIXPOSIXPOSIX标准标准标准标准这些系统调用编程接口主这些系统调用编程接口主这些系统调用编程接口主这些系统调用编程接口主要通过要通过要通过要通过C C C C库库库库(libc.solibc.solibc.solibc.so)实现的实现的实现的实现的系统调用系统调用系统调用系统调用、APIAPIAPIAPI与系统命令之间的关系与系统命令之间的关系与系统命令之间的关系与系统命令之间的关系文件文件文件文件I/OI/OI/OI/O函数函数函数函数可用的文件可用的文件可用的文件可用的文件I/OI/OI/OI/O函数函数函数函数打开文件打开文件打开文件打开文件读文件读文件读文件读文件写文件等等写文件等等写文件等等写文件等等大多数大多数大多数大多数linuxlinuxlinuxlinux文件文件文件文件I/OI/OI/OI/O只需用到只需用到只需用到只需用到5 5 5 5个函数个函数个函数个函数:openopenopenopenreadreadreadreadwritewritewritewritelseek lseek lseek lseek 以及以及以及以及closecloseclosecloseopenopenopenopen函数函数函数函数#include#include#include#include#include#include#include#include#include#include#include#include int open(const char*pathname,int oflag,int open(const char*pathname,int oflag,int open(const char*pathname,int oflag,int open(const char*pathname,int oflag,“/*,/*,/*,/*,mode_t mode*/);mode_t mode*/);mode_t mode*/);mode_t mode*/);返回返回返回返回:若成功为文件描述符若成功为文件描述符若成功为文件描述符若成功为文件描述符,若出错为若出错为若出错为若出错为-1 1 1 1文件描述符文件描述符文件描述符文件描述符对于内核而言对于内核而言对于内核而言对于内核而言,所有打开文件都由文件描述符引用所有打开文件都由文件描述符引用所有打开文件都由文件描述符引用所有打开文件都由文件描述符引用文件文件文件文件描述符是一个非负整数描述符是一个非负整数描述符是一个非负整数描述符是一个非负整数当打开一个现存文件或创建一个当打开一个现存文件或创建一个当打开一个现存文件或创建一个当打开一个现存文件或创建一个新文件时新文件时新文件时新文件时,内核向进程返回一个文件描述符内核向进程返回一个文件描述符内核向进程返回一个文件描述符内核向进程返回一个文件描述符当读当读当读当读写一写一写一写一个文件时个文件时个文件时个文件时,用用用用o p e no p e no p e no p e n返回的文件描述符标识该文件返回的文件描述符标识该文件返回的文件描述符标识该文件返回的文件描述符标识该文件,将其将其将其将其作为参数传送给作为参数传送给作为参数传送给作为参数传送给r e a dr e a dr e a dr e a d或或或或w r i t ew r i t ew r i t ew r i t e在在在在P O S I X.1P O S I X.1P O S I X.1P O S I X.1应用程序中应用程序中应用程序中应用程序中,整数整数整数整数0 0 0 01 1 1 12 2 2 2应被代换成符应被代换成符应被代换成符应被代换成符号常数号常数号常数号常数:STDIN_FILENOSTDIN_FILENOSTDIN_FILENOSTDIN_FILENOSTDOUT_FILENOSTDOUT_FILENOSTDOUT_FILENOSTDOUT_FILENOSTDERR_FILENOSTDERR_FILENOSTDERR_FILENOSTDERR_FILENO这些常数都定义在头文件这些常数都定义在头文件这些常数都定义在头文件这些常数都定义在头文件 中中中中文件描述符的范围是文件描述符的范围是文件描述符的范围是文件描述符的范围是0 OPEN_MAX 0 OPEN_MAX 0 OPEN_MAX 0 OPEN_MAX 早期的早期的早期的早期的UNIXUNIXUNIXUNIX版本版本版本版本采用的上限值是采用的上限值是采用的上限值是采用的上限值是1 9(1 9(1 9(1 9(允许每个进程打开允许每个进程打开允许每个进程打开允许每个进程打开2 02 02 02 0个文件个文件个文件个文件),现在现在现在现在很多系统则将其增加至很多系统则将其增加至很多系统则将其增加至很多系统则将其增加至256256256256。openopenopenopen函数说明函数说明函数说明函数说明参数参数参数参数pathname pathname pathname pathname 指向想要打开的文件路径字符串指向想要打开的文件路径字符串指向想要打开的文件路径字符串指向想要打开的文件路径字符串参数参数参数参数flags flags flags flags 表示打开文件的方式表示打开文件的方式表示打开文件的方式表示打开文件的方式,例如例如例如例如:O_RDONLYO_RDONLYO_RDONLYO_RDONLY以只读方式打开文件以只读方式打开文件以只读方式打开文件以只读方式打开文件O_WRONLYO_WRONLYO_WRONLYO_WRONLY以只写方式打开文件以只写方式打开文件以只写方式打开文件以只写方式打开文件O_RDWRO_RDWRO_RDWRO_RDWR以读写方式打开文件以读写方式打开文件以读写方式打开文件以读写方式打开文件以上三种打开方式是互斥的以上三种打开方式是互斥的以上三种打开方式是互斥的以上三种打开方式是互斥的,即即即即flagsflagsflagsflags只能选择一种只能选择一种只能选择一种只能选择一种,但可但可但可但可以利用以利用以利用以利用|运算符组合运算符组合运算符组合运算符组合O_APPENDO_APPENDO_APPENDO_APPEND 每次写时都加到文件的尾端每次写时都加到文件的尾端每次写时都加到文件的尾端每次写时都加到文件的尾端O_CREATO_CREATO_CREATO_CREAT 若此文件不存在则创建它若此文件不存在则创建它若此文件不存在则创建它若此文件不存在则创建它使用此选择项时使用此选择项时使用此选择项时使用此选择项时,需需需需同时说明第三个参数同时说明第三个参数同时说明第三个参数同时说明第三个参数modemodemodemode,用其说明该新文件的存取许可用其说明该新文件的存取许可用其说明该新文件的存取许可用其说明该新文件的存取许可权位权位权位权位O_EXCLO_EXCLO_EXCLO_EXCL 如果同时指定了如果同时指定了如果同时指定了如果同时指定了O_CREATO_CREATO_CREATO_CREAT,而文件已经存在而文件已经存在而文件已经存在而文件已经存在,则出则出则出则出错错错错这可测试一个文件是否存在这可测试一个文件是否存在这可测试一个文件是否存在这可测试一个文件是否存在,如果不存在则创建此文如果不存在则创建此文如果不存在则创建此文如果不存在则创建此文件成为一个原子操作件成为一个原子操作件成为一个原子操作件成为一个原子操作O_TRUNCO_TRUNCO_TRUNCO_TRUNC 如果此文件存在如果此文件存在如果此文件存在如果此文件存在,而且为只读或只写成功打开而且为只读或只写成功打开而且为只读或只写成功打开而且为只读或只写成功打开,则将其长度截短为则将其长度截短为则将其长度截短为则将其长度截短为0 0 0 0perrorperrorperrorperror函数说明函数说明函数说明函数说明#include#include#include#include void perror(const char*s);void perror(const char*s);void perror(const char*s);void perror(const char*s);函数说明函数说明函数说明函数说明:perrorperrorperrorperror函数用来将上一个函数发生的错误的原因输出到函数用来将上一个函数发生的错误的原因输出到函数用来将上一个函数发生的错误的原因输出到函数用来将上一个函数发生的错误的原因输出到标准错误标准错误标准错误标准错误(stderrstderrstderrstderr)参数参数参数参数s s s s所指的字符串会先打印所指的字符串会先打印所指的字符串会先打印所指的字符串会先打印,后后后后面再输出错误原因的字符串面再输出错误原因的字符串面再输出错误原因的字符串面再输出错误原因的字符串此错误原因依照全局此错误原因依照全局此错误原因依照全局此错误原因依照全局errnoerrnoerrnoerrno的值来决定要输出的字符串的值来决定要输出的字符串的值来决定要输出的字符串的值来决定要输出的字符串返回值返回值返回值返回值无无无无closeclosecloseclose函数函数函数函数close函数用于关闭一个的打开文件函数用于关闭一个的打开文件函数用于关闭一个的打开文件函数用于关闭一个的打开文件#include#include#include#include int close(int int close(int int close(int int close(int filedesfiledesfiledesfiledes);返回返回返回返回:若成功为若成功为若成功为若成功为0 0 0 0,若出错为若出错为若出错为若出错为-1 1 1 1当一个进程终止时当一个进程终止时当一个进程终止时当一个进程终止时,它所有的打开文件都由内核自动它所有的打开文件都由内核自动它所有的打开文件都由内核自动它所有的打开文件都由内核自动关闭关闭关闭关闭很多程序都使用这一功能而不显式地用很多程序都使用这一功能而不显式地用很多程序都使用这一功能而不显式地用很多程序都使用这一功能而不显式地用c l o s ec l o s ec l o s ec l o s e关关关关闭打开的文件闭打开的文件闭打开的文件闭打开的文件readreadreadread函数函数函数函数#include#include#include#include ssize_t read(int fd,void*buf,sszie_t count);ssize_t read(int fd,void*buf,sszie_t count);ssize_t read(int fd,void*buf,sszie_t count);ssize_t read(int fd,void*buf,sszie_t count);函数说明函数说明函数说明函数说明readreadreadread函数由以打开的文件读取数据函数由以打开的文件读取数据函数由以打开的文件读取数据函数由以打开的文件读取数据,readreadreadread函数会把参数函数会把参数函数会把参数函数会把参数fdfdfdfd所指的文所指的文所指的文所指的文件传送件传送件传送件传送countcountcountcount个字节到个字节到个字节到个字节到bufbufbufbuf指针所指的内存中指针所指的内存中指针所指的内存中指针所指的内存中若参数若参数若参数若参数countcountcountcount为为为为0 0 0 0,则则则则readreadreadread不会有作用并返回不会有作用并返回不会有作用并返回不会有作用并返回0 0 0 0返回值为实际从文件中读到的字节数返回值为实际从文件中读到的字节数返回值为实际从文件中读到的字节数返回值为实际从文件中读到的字节数,如果返回如果返回如果返回如果返回0 0 0 0,表示已到达文件尾或是无可读取的数据表示已到达文件尾或是无可读取的数据表示已到达文件尾或是无可读取的数据表示已到达文件尾或是无可读取的数据,此外文件读此外文件读此外文件读此外文件读写位置会随读取到的字节移动写位置会随读取到的字节移动写位置会随读取到的字节移动写位置会随读取到的字节移动备注备注备注备注如果顺利如果顺利如果顺利如果顺利readreadreadread会返回实际读到的字节数会返回实际读到的字节数会返回实际读到的字节数会返回实际读到的字节数,最好能将返回最好能将返回最好能将返回最好能将返回值与参数值与参数值与参数值与参数countcountcountcount做比较做比较做比较做比较,若返回的字节数比若返回的字节数比若返回的字节数比若返回的字节数比countcountcountcount的值小的值小的值小的值小,则有可能读到了文件尾则有可能读到了文件尾则有可能读到了文件尾则有可能读到了文件尾从管道或是终端读取从管道或是终端读取从管道或是终端读取从管道或是终端读取,或是或是或是或是readreadreadread被信号中断了读取动作被信号中断了读取动作被信号中断了读取动作被信号中断了读取动作当有错误发生时当有错误发生时当有错误发生时当有错误发生时,返回返回返回返回-1 1 1 1,错误原因存入错误原因存入错误原因存入错误原因存入errnoerrnoerrnoerrno中中中中,发生这类错误时发生这类错误时发生这类错误时发生这类错误时,文件读写位文件读写位文件读写位文件读写位置无法预期置无法预期置无法预期置无法预期writewritewritewrite函数函数函数函数#include#include#include#include ssize_t writessize_t writessize_t writessize_t write(int fdint fdint fdint fd,const void*bufconst void*bufconst void*bufconst void*buf,size_t countsize_t countsize_t countsize_t count););););函数说明函数说明函数说明函数说明函数函数函数函数writewritewritewrite会把参数会把参数会把参数会把参数bufbufbufbuf所指的内存写入所指的内存写入所指的内存写入所指的内存写入countcountcountcount个字节到参个字节到参个字节到参个字节到参数数数数fdfdfdfd所指的文件中所指的文件中所指的文件中所指的文件中,读写位置会随之移动读写位置会随之移动读写位置会随之移动读写位置会随之移动返回值返回值返回值返回值如果顺利如果顺利如果顺利如果顺利writewritewritewrite会返回实际写入的字节数会返回实际写入的字节数会返回实际写入的字节数会返回实际写入的字节数当有当有当有当有错误发生时错误发生时错误发生时错误发生时,则返回则返回则返回则返回-1 1 1 1;错误代码存放入错误代码存放入错误代码存放入错误代码存放入errnoerrnoerrnoerrno中中中中fdopenfdopenfdopenfdopen函数函数函数函数#include#include#include#include FILE*fdopen(int fildes,const char*mode);FILE*fdopen(int fildes,const char*mode);FILE*fdopen(int fildes,const char*mode);FILE*fdopen(int fildes,const char*mode);函数说明fdopenfdopenfdopenfdopen将将将将fildesfildesfildesfildes文件描述符转换为文件指针后返回文件描述符转换为文件指针后返回文件描述符转换为文件指针后返回文件描述符转换为文件指针后返回,modemodemodemode表示文件表示文件表示文件表示文件指针的流形态指针的流形态指针的流形态指针的流形态,与原来文件描述符的读写形式相同与原来文件描述符的读写形式相同与原来文件描述符的读写形式相同与原来文件描述符的读写形式相同返回值正确返回指向该流的文件指针正确返回指向该流的文件指针正确返回指向该流的文件指针正确返回指向该流的文件指针,错误错误错误错误NULLNULLNULLNULLfgetsfgetsfgetsfgets函数说明函数说明函数说明函数说明#include char*fgets(char*s,int size,FILE*stream);函数说明函数说明函数说明函数说明函数函数函数函数fgetsfgetsfgetsfgets用来从参数用来从参数用来从参数用来从参数streamstreamstreamstream所指的文件内读入字符并存到参数所指的文件内读入字符并存到参数所指的文件内读入字符并存到参数所指的文件内读入字符并存到参数s s s s所所所所指的内存空间指的内存空间指的内存空间指的内存空间,直到出现换行字符直到出现换行字符直到出现换行字符直到出现换行字符读到文件尾或是已读了读到文件尾或是已读了读到文件尾或是已读了读到文件尾或是已读了sizesizesizesize-1 1 1 1个字符为止个字符为止个字符为止个字符为止,最后会加上最后会加上最后会加上最后会加上NULLNULLNULLNULL作为字符串结束作为字符串结束作为字符串结束作为字符串结束返回值返回值返回值返回值成功返回成功返回成功返回成功返回s s s s指针指针指针指针,错误返回错误返回错误返回错误返回NULLNULLNULLNULL