文件描述符是在 Unix 和类 Unix 操作系统中用于标识已打开文件或 I/O 设备的整数
我们都知道,使用 open 打开文件可以拿到文件描述符 fd,然后我们可以通过文件描述符 fd 对文件进行写 (write) 和读 (read) 以及关闭文件 (close),那么,为什么我们可以通过文件描述符做这么多事情呢?
其实,文件描述符的本质是 struct file* 指针数组的数组下标。
在进程控制块 task_struct 中,有一个指向文件结构体的指针:struct files_struct* ,这个指针指向结构体 struct files_struct,而 struct files_struct 里有一个指针数组:struct file* fd_array[ ] ,每一个指针都指向一个 struct file 文件对象,文件描述符 fd 的本质就是 fd_array[ ] 这个指针数组的下标。
在使用 open() 函数时,就是将磁盘中的文件加载到内存,创建一个 struct file 对象,然后将其属性内容等填好,然后链接到文件队列中,再返回新创建的 struct file 的地址,填到 fd_array[ ] 最小的,未被使用的下标中,再返回这个下标,就让我们拿到了文件描述符 fd。
补充:fd 的分配规则:最小的未被使用的下标,分配给最新打开的文件。
使用 write() 函数,就是先用 文件描述符 fd 找到对应的 struct file 文件对象,然后将 buf 中的数据填入缓冲区中,再由操作系统将缓冲区刷新到磁盘里,完成写操作。
使用 read() 函数,就是先用 文件描述符 fd 找到对应的 struct file 文件对象,然后读取缓冲区的数据到 buf 中,如果缓冲区内没有数据,就将磁盘中的数据导入到缓冲区,再读。
而使用 close() 函数,就是先用 文件描述符 fd 找到对应的 struct file 文件对象,然后使用 free 将对应的 struct file 文件对象释放掉,完成资源释放。