提供Discuz ,ECShop ,PHPCMS ,帝国CMS ,CSS教程 ,PHP教程 ,DedeCMS ,WordPress ,HTML教程等cms问题查询.
当前位置: 运维 > Linux > 文件描述符与FILE观点引见【Linux】,FILE,描述,文件

1. 文件形貌符(重点)

在Linux体系中一切皆能够看成是文件,文件又可分为:一般文件、目次文件、链接文件和装备文件。文件形貌符(file descriptor)是内核为了高效治理已被翻开的文件所建立的索引,其是一个非负整数(通常是小整数),用于指代被翻开的文件,一切实行I/O操纵的体系挪用都经由过程文件形貌符。顺序方才启动的时刻,0是规范输入,1是规范输出,2是规范毛病。假如此时去翻开一个新的文件,它的文件形貌符会是3。

1.1观点引见

文件形貌符的操纵(如: open(),creat(),close(),read()))返回的是一个文件形貌符,它是int范例的整数,即fd,其本质是文件形貌符表中的下标,它起到一个索引的作用,历程经由过程PCB中的文件形貌符表找到该fd所指向的文件指针filp。每一个历程在PCB(Process Control Block)即历程掌握块中都保留着一份文件形貌符表,文件形貌符就是这个表的索引,文件形貌表中每一个表项都有一个指向已翻开文件的指针; 已翻开的文件在内核顶用file构造体示意,文件形貌符表中的指针指向file构造体。每翻开一个文件,fd默许从最小的未被运用的下标最先分派。文件形貌符的瑕玷:不能移植到UNIX之外的体系上去,也不直观。

下面画张图来示意它们之间的关联:

而每一个文件中又主要包含以下这些信息:

1.2图表诠释

file构造体中保护File Status Flag(file构造体的成员f_flags)和当前读写位置(file构造体的成员f_pos)。在上图中,历程1和历程2都翻开统一文件,然则对应差别的file构造体,因而能够有差别的File Status Flag和读写位置。file构造体中比较主要的成员另有f_count,示意援用计数(Reference Count),背面我们会讲到,dupfork等体系挪用会致使多个文件形貌符指向统一个file构造体,比方有fd1fd2都援用统一个file构造体,那末它的援用计数就是2,当close(fd1)时并不会开释file构造体,而只是把援用计数减到1,假如再close(fd2),援用计数就会减到0同时开释file构造体,这才真的封闭了文件。

每一个file构造体都指向一个file_operations构造体,这个构造体的成员都是函数指针,指向完成种种文件操纵的内核函数。比方在用户顺序中read一个文件形貌符,read经由过程体系挪用进入内核,然后找到这个文件形貌符所指向的file构造体,找到file构造体所指向的file_operations构造体,挪用它的read成员所指向的内核函数以完成用户要求。在用户顺序中挪用lseekreadwriteioctlopen等函数,终究都由内核挪用file_operations的各成员所指向的内核函数完成用户要求。file_operations构造体中的release成员用于完成用户顺序的close要求,之所以叫release而不叫close是由于它不一定真的封闭文件,而是削减援用计数,只需援用计数减到0才封闭文件。关于统一个文件体系上翻开的通例文件来讲,readwrite等文件操纵的步骤和要领应当是一样的,挪用的函数应当是雷同的,所以图中的三个翻开文件的file构造体指向统一个file_operations构造体。假如翻开一个字符装备文件,那末它的readwrite操纵一定和通例文件不一样,不是读写磁盘的数据块而是读写硬件装备,所以file构造体应当指向差别的file_operations构造体,个中的种种文件操纵函数由该装备的驱动顺序完成。

每一个file构造体都有一个指向dentry构造体的指针,“dentry”是directory entry(目次项)的缩写。我们传给openstat等函数的参数的是一个途径,比方/home/akaedu/a,须要依据途径找到文件的inode。为了削减读盘次数,内核缓存了目次的树状构造,称为dentry cache,个中每一个节点是一个dentry构造体,只需沿着途径各部份的dentry搜刮即可,从根目次/找到home目次,然后找到akaedu目次,然后找到文件a。dentry cache只保留近来访问过的目次项,假如要找的目次项在cache中没有,就要从磁盘读到内存中。

每一个dentry构造体都有一个指针指向inode构造体。inode构造体保留着从磁盘inode读上来的信息。在上图的例子中,有两个dentry,离别示意/home/akaedu/a/home/akaedu/b,它们都指向统一个inode,申明这两个文件互为硬链接。inode构造体中保留着从磁盘分区的inode读上来信息,比方一切者、文件大小、文件范例和权限位等。每一个inode构造体都有一个指向inode_operations构造体的指针,后者也是一组函数指针指向一些完成文件目次操纵的内核函数。和file_operations差别,inode_operations所指向的不是针对某一个文件举行操纵的函数,而是影响文件和目次规划的函数,比方增加删除文件和目次、跟踪标记链接等等,属于统一文件体系的各inode构造体能够指向统一个inode_operations构造体。

inode构造体有一个指向super_block构造体的指针。super_block构造体保留着从磁盘分区的超等块读上来的信息,比方文件体系范例、块大小等。super_block构造体的s_root成员是一个指向dentry的指针,示意这个文件体系的根目次被mount到哪里,在上图的例子中这个分区被mount/home目次下。

filedentryinodesuper_block这几个构造体组成了VFS(假造文件体系VFS,Virtual Filesystem)的中心观点。

1.3对文件形貌符的操纵

(1).检察Linux文件形貌符

 1 [root@localhost ~]# sysctl -a | grep -i file-max --color 3 fs.file-max = 392036 5 [root@localhost ~]# cat /proc/sys/fs/file-max 7 392036 9 [root@localhost ~]# ulimit -n11 102413 [root@localhost ~]#

Linux下最大文件形貌符的限定有两个方面,一个是用户级的限定,别的一个则是体系级限定。

体系级限定:sysctl敕令和proc文件体系中检察到的数值是一样的,这属于体系级限定,它是限定一切用户翻开文件形貌符的总和

用户级限定:ulimit敕令看到的是用户级的最大文件形貌符限定,也就是说每一个用户登录后实行的顺序占用文件形貌符的总数不能超过这个限定

(2).修正文件形貌符的值

1 [root@localhost ~]# ulimit-SHn 102402 [root@localhost ~]# ulimit  -n3 102404 [root@localhost ~]#

以上的修正只对当前会话起作用,是暂时性的,假如须要永远修正,则要修正以下:

1 [root@localhost ~]# grep -vE'^$|^#' /etc/security/limits.conf2 *                hard nofile                  40963 [root@localhost ~]#
1 //默许配置文件中只需hard选项,soft 指的是当前体系见效的设置值,hard 表明体系中所能设定的最大值2 [root@localhost ~]# grep -vE'^$|^#' /etc/security/limits.conf3 *      hard         nofile       102404 *      soft         nofile      102405 [root@localhost ~]#6 // soft<=hard soft的限定不能比hard限定高

(3).修正体系限定

1 [root@localhost ~]# sysctl -wfs.file-max=4000002 fs.file-max = 4000003 [root@localhost ~]# echo350000 > /proc/sys/fs/file-max  //重启后失效4 [root@localhost ~]# cat /proc/sys/fs/file-max5 3500006 [root@localhost ~]#

//以上是暂时修正文件形貌符
//永远修正把fs.file-max=400000增加到/etc/sysctl.conf中,运用sysctl -p即可

1.4用顺序检察文件形貌符

下面的顺序,翻开/home/shenlan/hello.c文件,假如此目次下没有hello.c文件,顺序自动建立,顺序中返回的文件形貌符为3。由于历程启动时,翻开了规范输入(0)、规范输出(1)和规范失足处置惩罚(2)三个文件,fd默许从最小的未被运用的下标最先分派,因而返回的文件形貌符为3

 1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<sys/stat.h> 4 #include<fcntl.h> 5 #include<stdlib.h> 6 int main() 7 { 8        int fd; 9        if((fd = open("/home/shenlan/fd.c",O_CREAT|O_WRONLY|O_TRUNC,0611))<0){10               perror("openfile fd.c error!\n");11               exit(1);12        }13        else{14               printf("openfile fd.c success:%d\n",fd);15        }16        if(close(fd) < 0){17               perror("closefile fd.c error!\n");18               exit(1);19        }20        else21               printf("closefile fd.c success!\n");22        exit(0);23 }

实行效果:

1.5历程翻开一个文件的细致流程

历程经由过程体系挪用open( )来翻开一个文件,实质上是取得一个文件形貌符,以便历程经由过程文件形貌符为衔接对文件举行其他操纵。历程翻开文件时,会为该文件建立一个file对象,并把该file对象存入历程翻开文件表中(文件形貌符数组),进而肯定了所翻开文件的文件形貌符。 open( )操纵在内核里经由过程sys_open( )完成的,sys_open( )将建立文件的dentryinodefile对象,并在file_struct构造体的历程翻开文件表fd_array[NR_OPEN_DEFAULT]中寻觅一个余暇表项,然后返回这个表项的下标(索引),即文件形貌符。建立文件的file对象时,将file对象的f_op指向了所属文件体系的操纵函数集file_operations,而该函数集又来自细致文件的i节点,因而假造文件体系就与现实文件体系的操纵衔接起来了。

2.C规范库中的FILE构造和文件形貌符

C言语中运用的是文件指针而不是文件形貌符做为I/O的句柄."文件指针(file pointer)"指向历程用户区中的一个被称为FILE构造的数据构造。FILE构造包含一个缓冲区和一个文件形貌符值.而文件形貌符值是文件形貌符表中的一个索引.从某种意义上说文件指针就是句柄的句柄。流(如: fopen)返回的是一个FILE构造指针, FILE构造是包含有文件形貌符的,FILE构造函数能够看做是对fd直接操纵的体系挪用的封装, 它的长处是带有I/O缓存。

从文件形貌符fd 到文件流 FILE* 的函数是
FILE* fdopen(int filedes,const char* mode);

初期的C规范库中,FILEstdio.h中定义Turbo C中,拜见谭浩强的《C顺序设计》,FILE构造体中包含成员fd,即文件形貌符。亦能够在装置的Ubuntu体系的/usr/include/stdio.h中找到struct _IO_FILE构造体,这个构造体比较庞杂,我们只体贴须要的部份-文件形貌符,然则在这个的构造体中,我们并没有发明与文件形貌符相干的诸如fd成员变量。此时,范例为int_fileno构造体成员引起了我们的注重,然则不能肯定其为文件形貌符。因而写个顺序测试是最好的方法,能够用以下的代码测试:

 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<sys/types.h> 4 #include<sys/stat.h> 5 #include<fcntl.h> 6 int main( ) 7 { 8        char buf[50] = {"ILOVE this game!"}; 9        FILE *myfile;10 11        myfile = fopen("2.txt","w+");12        if(!myfile){13               printf("error:openfile failed!\n");14        }15        printf("The openedfile's descriptor is %d\n",myfile->_fileno);16        if(write(myfile->_fileno,buf,50)< 0){17               perror("error:writefile failed!\n");18               exit(1);19        }else{20               printf("writefile successed!\n");21        }22        exit(0);23 }

顺序中,运用fopen函数以读写翻开2.txt文件,假如不存在2.txt文件,则建立此文件。并将其返回的FILE指针myfile。运用printf向规范终端打印出myfile->_fileno的值,并将myfile->_fileno作为文件形貌符传递给write体系挪用,向翻开的文件写入缓冲区数据。然后运用cat敕令检察2.txt的内容。实行的效果如图所示。_fileno的值为3,由于规范输入、输出、失足为012。输出效果以下:
因而,_fileno成员即为操纵体系翻开文件返回的句柄(windows体系)或文件形貌符。深切进修能够浏览人民邮电出版社《C规范库》。固然还能够浏览/glibc-2.9/manual/io.txti文件。Linux中,文件的形貌符分派是从小到大逐一查询文件形貌符是不是已运用,然后再分派,也能够写顺序测试。

文件形貌符表也称文件形貌符数组,个中存放了一个历程所翻开的一切文件。文件形貌符数组包含在历程翻开的文件表files_struct构造中。/include/linux/fdtable.h中定义,为一个指向file范例的指针数组---fd_array[NR_OPEN_DEFAULT],个中NR_OPEN_DEFAULT也在fdtable.h中定义,这是一个和细致的CPU体系构造有关的变量,#define NR_OPEN_DEFAULTBITS_PER_LONG

FILE构造和文件形貌符、file构造之间的关联能够用下图来示意:

以上就是文件形貌符与FILE观点引见的细致内容,更多请关注ki4网别的相干文章!

「梦想一旦被付诸行动,就会变得神圣,如果觉得我的文章对您有用,请帮助本站成长」

分享到:
赞(0) 打赏

支付宝扫一扫打赏

微信扫一扫打赏

标签:

上一篇:

下一篇:

相关推荐

0 条评论关于"文件描述符与FILE观点引见【Linux】,FILE,描述,文件"

最新评论

    暂无留言哦~~

博客简介

看古风美女插画Cos小姐姐,素材合集图集打包下载:炫龙网,好看二次元插画应有尽有,唯美小姐姐等你来。

友情链接

他们同样是一群网虫,却不是每天泡在网上游走在淘宝和网游之间、刷着本来就快要透支的信用卡。他们或许没有踏出国门一步,但同学却不局限在一国一校,而是遍及全球!申请交换友链

服务热线:
 

 QQ在线交流

 旺旺在线