文件描述符
在Linux中,有着一切文件的说法,那么在我们打开这个文件的时候,就会获得该文件的文件描述符。
每一个进程在PCB(task_struct)中都保存着进程的相关信息,用来描述进程,其中就保存着一份文件描述符表,而打开文件获得的这个文件描述符。就是这个文件描述符表的索引,在文件描述符表中,每个表项都指向一个已经打开文件的指针,其实文件描述符表就是一个数组,文件描述符就是这个描述符表的下标。
在程序运行的时候,系统会默认打开三个输入输出流:标准输入,标准输出,标准错误,在三个输入输出流,在文件描述符表中占据了前三个下标,依次是0,1,2;
那么之后,在程序中打开mylog文件,那么mylog的文件标识符就是3,如果在程序的开始,就关闭标准输入,标准输出,标准错误其中的一个,比如:我们用close(1),关闭标准输出,那么再打开mylog文件,它的文件描述符就会变成1。
此时,我们也得到文件标识符的分配规律:从当前未被分配的最小的文件标识符开始分配。
但是 文件标识符有一个缺点,就是平台的移植性较差,
总结:
每一个进程在PCB中都有维护一份文件描述符表,也就是一个数组,而文件描述符就是这个表的索引,也就是下标,当你用open函数打开一个文件的时候,返回的就是这个文件描述符在文件描述符表中的下标,在进程中打开的文件都将通过文件描述符来引用。
那么当我们在文件描述符表中,按照文件描述符找到对应的表项的时候,里面存放着一个已打开文件的指针,该指针的类型是FILE*,指向的是一个FILE结构体,而这个FILE结构体就是在内核中描述文件属性的结构体
文件指针
在C语言中我们经常通过FILE* fp = fopen("test.txt","rb");来打开一个文件,而我们用的指针的类型FILE其实是一个结构体类型,在VC6中,给出了下面的定义
给出的这个结构体就是,在内核中描述文件属性的结构体,包含在stdio.h的头文件中。
实际上我们在使用的时候不需要关心FILE的结构,FILE结构是间接地操纵系统的文件控制块(FCB)来实现对文件的操作的在这里我们不做过多的说明。
但是在FILE的结构体中,我们有注意到:int _file这个成员,他就是我们在上面提到的文件描述符,也就是文件描述符表的索引,之前的文件描述符现在作为FILE结构体的成员,类似于于FILE把文件描述符再一次封装了一遍。
open()和fopen()的区别:
open函数:返回值是一个文件描述符,内核在每一个PCB中维护一个文件描述符表,通过这个文件描述符就可以知道,在表中就可以找到相关文件。
fopen函数:返回值是一个文件指针,也就是指向FILE结构体的指针
Tip:限于编者水平,文章难免有缺漏之处,欢迎各位前来补充
如需转载,请注明出处