您好,欢迎访问三七文档
第二章设备和文件IO本章目标•理解设备和文件的关系•理解系统调用和系统API等关系,掌握系统调用的工作过程•掌握系统调用open/read/write/fcntl等使用Linux中的设备管理•Linux设备管理概述在Linux系统中,用户是通过文件系统与设备接口的。所有设备都作为特别文件,从而在设备管理上具有下列特性。–(1)每个设备都对应文件系统中的一个索引节点,都有一个文件名。–(2)应用程序通常可以通过系统调用open()打开设备文件,建立起与目标设备的连接。–(3)对设备的使用类似于对文件的存取。–(4)设备驱动程序都是系统内核的一部分,它们必须为系统内核或者它们的子系统提供一个标准的接口。–(5)设备驱动程序使用一些标准的内核服务,如内存分配等。设备工作原理设备分类•按设备属主关系–系统设备–用户设备•按设备信息交换单位来分–字符设备–块设备•按设备共享属性来分–独享设备–共享设备Linux设备操作•设备或文件操作两种方式:–用户编程接口API–系统调用系统调用•系统调用是操作系统提供给用户的一组“特殊”接口•系统调用并非直接和程序员或系统管理员直接打交道,而是通过软中断的方式向内核提交请求,从而获取内核函数的服务入口(系统调用表)•系统调用让系统从用户空间进入内核空间内运行,运行后将结果返回给应用程序(内核态-用户空间)系统调用和系统API等区别•系统API–主要是通过C库libc来实现,程序员多采用这种方式与内核交互,这些API通过系统调用来实现•系统命令–系统管理员采用系统命令与内核交互,是一个可执行文件,通过系统API及系统调用来实现•外壳程序–一系列系统命令和SHELL脚本共同组合成的程序。C库的文件操作函数名功能fopen()打开文件fclose()关闭文件fputc()将字符写入文件中fgetc()从文件中读取字符fread()将数据从文件中读到缓冲区fwrite()将数据从缓冲区写入文件fseek()在文件中搜索指定位置fprintf()操作类似于printf(),但是用于文件fscanf()操作类似于scanf(),但是用于文件feof()如果到达文件结尾,返回trueferror()如果出错,返回truerewind()将文件位置指示器重新置于文件开头remove()删除文件fflush()将内部缓冲区的数据写入指定文件文件系统调用•open系统调用•read系统调用•write系统调用•create系统调用•close系统调用•mkdir系统调用•…文件描述符fd•每个进程PCB结构中有文件描述符指针,指向files_struct的文件描述符表,记录每个进程打开的文件列表•系统内核不允许应用程序访问进程的文件描述符表,只返回这些结构的索引即文件描述符ID(FileDescription)给应用程序•Linux系统中,应用程序通过这些文件描述符来实现让内核对文件的访问•每个进程能够访问的文件描述符是有限制的,通过#ulimit–n可以查看特殊文件描述符号•标准输入STDIN_FILENO•标准输出STDOUT_FILENO•标准错误STDERR_FILENO每个进程被加载后,默认打开0,1,2这三个文件描述符open系统调用2-1•有几种方法可以获得允许访问文件的文件描述符。最常用的是使用open()(打开)系统调用–函数原型intopen(constchar*path,intflags);–参数path:文件的名称,可以包含(绝对和相对)路径flags:文件打开模式–返回值打开成功,返回文件描述符;打开失败,返回-1open系统调用2-2–函数原型intopen(constchar*path,intflags,mode_tmode);–参数path:文件的名称,可以包含(绝对和相对)路径flags:文件打开模式mode:用来规定对该文件的所有者,文件的用户组及系统中其他用户的访问权限,则文件权限为:mode&(~umask)–返回值打开成功,返回文件描述符;打开失败,返回-1打开文件的方式打开方式描述O_RDONLY打开一个供读取的文件O_WRONLY打开一个供写入的文件O_RDWR打开一个可供读写的文件O_APPEND写入的所有数据将被追加到文件的末尾O_CREAT打开文件,如果文件不存在则建立文件O_EXCL如果已经置O_CREAT且文件存在,则强制open()失败O_TRUNC在open()时,将文件的内容清空所有这些标志值的符号名称可以通过#includefcntl.h访问访问权限打开方式描述S_IRUSR文件所有者的读权限位S_IWUSR文件所有者的写权限位S_IXUSR文件所有者的执行权限位S_IRWXUS_IRUSR|S_IWUSR|S_IXUSRS_IRGRP文件用户组的读权限位S_IWGRP文件用户组的写权限位S_IXGRP文件用户组的执行权限位S_IRWXGS_IRGRP|S_IWGRP|S_IXGRPS_IROTH文件其他用户的读权限位S_IWOTH文件其他用户的写权限位S_IXOTH文件其他用户的执行权限位S_IRWXOS_IROTH|S_IWOTH|S_IXOTH文件打开示例#includefcntl.h#includesys/stat.h#includestdio.hvoidmain(){intoutfd=0;outfd=open(“myfile,O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP);if(outfd==-1){perror(“failtoopenfile\n”);exit(-1);}else{perror(“successtoopenfile\n”);}close(outfd);//关闭文件描述符}关闭文件close•将进程中fd对应的文件描述表结构释放–函数原型:intclose(intfd);–函数参数:fd:要关闭的文件的文件描述符–返回值如果出现错误,返回-1调用成功返回0read系统调用•一旦有了与一个打开文件描述相连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节•函数原型:intread(intfd,void*buf,size_tnbytes);参数–fd:想要读的文件的文件描述符–buf:指向内存块的指针,从文件中读取来的字节放到这个内存块中–nbytes:从该文件复制到buf中的字节个数返回值如果出现错误,返回-1返回从该文件复制到规定的缓冲区中的字节数,文件结束,返回0否则write系统调用•用write()系统调用将数据写到一个文件中函数原型:intwrite(intfd,void*buf,size_tnbytes);函数参数:-fd:要写入的文件的文件描述符-buf:指向内存块的指针,从这个内存块中读取数据写入到文件中-nbytes:要写入文件的字节个数返回值如果出现错误,返回-1如果写入成功,则返回写入到文件中的字节个数write()示例#includestdio.h#includefcntl.h#includesys/stat.hvoidmain()intoutfd=0,r_size=0;charbuf[]=“Helloworld!!”;outfd=open(“first”,O_WONLY|O_TRUNC|O_CREAT,S_IRWXU);if(outfd0){r_size=write(outfd,buf,sizeof(buf));if(r_size0){printf(“writedatatofilesuccess”);}close(outfd);}}close系统调用•为了重新利用文件描述符,用close()系统调用释放打开的文件描述符函数原型:intclose(intfd);函数参数:-fd:要关闭的文件的文件描述符返回值如果出现错误,返回-1调用成功返回0文件的随机读写•到目前为止的所有文件访问都是顺序访问。这是因为所有的读和写都从当前文件的偏移位置开始,然后文件偏移值自动地增加到刚好超出读或写结束时的位置,使它为下一次访问作好准备。•有个文件偏移这样的机制,在Linux系统中,随机访问就变得很简单,你所需做的只是将当前文件移值改变到有关的位置,它将迫使一次read()或write()发生在这一位置。(除非文件被O_APPEND打开,在这种情况下,任何write调用仍将发生在文件结束处)lseek系统调用2-1•功能说明:通过指定相对于开始位置、当前位置或末尾位置的字节数来重定位curp,这取决于lseek()函数中指定的位置•原型:off_tlseek(intfd,off_toffset,intbase);需设置的文件标识符偏移量搜索的起始位置返回值:返回新的文件偏移值lseek系统调用2-2•base表示搜索的起始位置,有以下几个值:(这些值定义在unistd.h)base文件位置SEEK_SET从文件开始处计算偏移SEEK_CUR从当前文件的偏移值计算偏移SEEK_END从文件的结束处计算偏移chmod和fchmod系统调用•功能说明:用来改变给定路径名pathname的文件的权限位•原型:intchmod(char*pathname,mode_tmode);文件的路径名权限位返回值:调用成功返回0,失败返回-1intfchmod(intfd,mode_tmode);文件描述符权限位chown和fchown系统调用•功能说明:用来改变文件所有者的识别号(ownerid)或者它的用户组识别号(groupID)•原型:intchown(char*pathname,uid_towner,gid_tgroup);文件的路径名所有者识别号返回值:调用成功返回0,失败返回-1intfchown(intfd,uid_towner,gid_tgroup);文件描述符用户组识别号所有者识别号用户组识别号mkdir系统调用•功能说明:用来创建一个称为pathname的新目录,它的权限位设置为mode•原型:intmkdir(char*pathname,mode_tmode);返回值:调用成功返回0,失败返回-1文件的路径名权限位rmdir系统调用•功能说明:删除一个空目录•原型:intrmdir(char*pathname);返回值:调用成功返回0,失败返回-1文件的路径名目录访问3-1•功能说明:打开一个目录•原型:DIR*opendir(char*pathname);返回值:打开成功,返回一个目录指针打开失败,则返回0文件的路径名目录访问3-2•功能说明:访问指定目录中下一个连接的细节•原型:structdirent*readdir(DIR*dirptr);返回值:返回一个指向dirent结构的指针,它包含指定目录中下一个连接的细节;没有更多连接时,返回NULL目录指针目录信息结构体structdirent{longd_ino;/*目录i结点编号*/off_td_off;/*目录文件开关至此目录进入点的位移*/unsignedshortd_reclen;/*d_name的长度*/chard_name[NAME_MAX+1];/*以NULL结尾的文件名*/}如果调用opendir打开某个目录之后,第一次调用readdir函数,则返回的是该目录下第一个文件的信息,第二次调用readdir函数返回该目录下第二个文件的信息,依此类推。如果该目录下已经没有文件信息可供读取,则返回NULL。目录访问3-3•功能说明:关闭一个已经打开的目录•原型:intclosedir(DIR*dirptr);返回值:调用成功返回0,失败返回-1目录指针目录操作示例#includesys/types.h#includedirent.h#includeunistd.h#includestdio.hintmy_read_dir(constchar*path){DIR*dir;st
本文标题:2、设备和文件IO
链接地址:https://www.777doc.com/doc-1305277 .html