带你理解文件描述符与文件流指针

文件描述符

文件描述符简单来说就是一个操作文件的句柄,一个非负整数。

具体分析
当我们打开一个文件的时候,这个文件就会被加载在内存上,linux总是会对文件进行描述组织的进行管理,因此这个文件的一系列相关信息就会被描述起来,进行描述的是一个叫做struct file的结构体。

我们知道,每个进程都是由一个pcb进行描述的,而在这个pcb中有一个叫做 struct files struct 的结构体,这个结构体中存储了每个已经打开文件的描述信息,也就是struct file结构体,这些结构体是由一个数组进行管理的–struct file *fd_arr[],这些数组存放的就是struct file 结构体首地址。通过数组里面的结构体首地址我们就能找到我们想要的文件了。
数组的下标其实就是我们所说的文件描述符。通过这个下标我们就可以对文件进行操作了。
在这里插入图片描述

因此打开文件使用完毕就要关闭文件,因为数组的大小是有限的。打开太多文件,就会导致不能打开新的文件,还有一个原因就是关闭文件也是释放资源的一种方式。因此使用完一定要关闭文件。

值得一提的是文件描述符在分配时遵从的最小未使用原则。

举个例子:
每个进程都会默认打开stdin stdout stderr三个文件,文件描述符分别为0 1 2,当我们关闭0,然后open一个新的文件时,新文件的描述符就会变成0。这个也是重定向的原理。

重定向

重定向:将数据不再写入原来的文件, 而是写入指定的文件。

实现方式就是替换原来文件描述符所指向的文件

比如我们本来想将文件写到标准输出上,那么这个时候我们将标准输出文件的文件描述符所指向的文件更改成我们指定的新文件,那么这次写入就会写入到我们所指定的文件。

简单来说就是操作系统操作的是文件描述符,而我们将深入到文件描述符的下一层 – 文件,瞒着操作系统将文件描述符指向的文件更换了。于是就实现了重定向。

dup2函数

int dup2(int oldfd, int newfd); -- 描述符重定向函数。
  • 作用: 让newfd指向oldfd指向的文件,这时候oldfd和newfd都能操作oldfd指向的文件。

linux重定向命令有 >> 追加重定向和 > 清空重定向。

文件流指针

库函数封装了系统调用接口,而文件流指针就是库函数层面进行文件IO操作的句柄,因此文件流指针其实是封装了文件描述符。

  • 文件描述符: 非负整数
  • 文件流指针:FILE结构体 typedef struct_IO_FILE FILE

其实就是对文件描述符进行了额外的封装,结构体中除了文件描述符,还有很多其他的成员。
在这里插入图片描述
两者到底有什么不同呢?

打个比方:比如我们向文件写入数据的时候:

  • 系统调用接口:直接写入数据。
  • 库函数:先写入到缓冲取,而这个缓冲取就是文件流指针中的结构体。同理exit退出会刷新缓冲取,_exit不会。

猜你喜欢

转载自blog.csdn.net/ifwecande/article/details/107452590