文件描述符(fd)是在文件IO中贯穿始终的类型,实际上是整形数、数组下标。
文件描述符优先使用当前可用范围内最小的一个,如果0,1,2,3,4,5,6都已被占用,但此时3关闭了,那么此时打开文件会占用3,而不是7。
FILE
FILE实际上是一个结构体。根据文件读完这一个字节,就知道读下一个字节;或者写完当前位置,移动到下一位置。所以,一定有一个文件位置指针,简称为pos。
文件描述符
文件描述符实现原理
每一个文件都有唯一的一个文件标识符inode。
通过open打开文件,会得到一个结构体,存储了这个文件的几乎所有信息。拿到该结构体的地址,就如同拿到一个FILE * 一样的东西。
将结构体的起始地址存储到了数组中的某个位置,实际上就是这种类型的结构体的指针存到了数组中。然后给用户的是当前存放指针的数组这块空间的下标,就是fd。
数组的0,1,2关联的是标准输入(stdin)、标准输出(stdout)、标准出错(stderr)。
fopen依赖于open产生,调用fopen产生一个结构体,那么一定也调用了open产生另一种结构体,所以,在FILE结构体中,一定有另一个成员fd。
fclose在释放FILE产生的结构体的同时,会把它依赖的open产生的结构体,通过调用close销毁掉。
一个进程中fd的最多个数
通过ulimit -a命令可以看到最多存在1024个文件,也就是说上面的数组大小为1024。
一个进程中打开两个文件
每个进程都有一个这样的数组,下图是一个进程中打开两个文件的状态。
所以如果两个进程打开同一个文件,不会拿到同一个结构体,谁打开就会产生一个这样的结构体。影响的原因是大家打开的是同一个文件,没有任何协议,就开始读写这个文件。
一个进程打开两次同一个文件
同一个文件在一个进程空间中打开两次。那么会产生两个结构体,拿到两个文件描述符,这两个文件描述符关联的是同一个文件。
将3号文件描述符close掉,那么文件指针置空,相关联的结构体会被free掉。
文件指针指向同一个结构体
将某个文件描述符对应的指针复制到另一个文件描述符对应的文件指针,那么这两个指针指向同一个结构体。
如果此时将3号文件描述符close掉,此时相关联的结构体不会被free掉,否则4号文件描述符的文件指针会成为野指针。
所以该结构体一定有一个计数器,反映该结构体被几个指针引用。
close一个文件描述符,那么关联的结构体count--,如果减完之后不为0,那么结构体不会被free掉。