文件描述符
文件描述符
定义
在Linux系统中,当我们打开或者创建一个文件时,系统会提供一个文件描述符作为该文件的“代号”,我们可以通过使用这个“代号”来对原文件进行一系列的读写操作。
在Linux中,文件描述符0、1、2是有特殊含义的。
0是标准输入(stdin)的文件描述符
1是标准输出(stdout)的文件描述符
2是标准错误(stderr)的文件描述符
文件描述符关联的数据结构
struct file
每个文件描述符都关联到内核一个 struct file 类型的结构体数据。struct file的结构体定义如下:
struct file {
......
atomic_long_t f_count; // 引用计数,管理文件对象的生命周期
struct mutex f_pos_lock; // 保护文件位置的互斥锁
loff_t f_pos; // 当前文件位置(读写位置)
......
struct path f_path; // 记录文件路径
struct inode *f_inode; // 指向与文件相关联的 inode 对象的指针,该对象用于维护文件元数据,如文件类型、访问权限等
const struct file_operations *f_op; // 指向文件操作函数表的指针,定义了文件支持的操作,如读、写、锁定等
......
void *private_data; // 存储特定驱动或模块的私有数据
......
}
这个数据结构记录了与文件相关的所有信息,其中比较关键的是 f_path 记录了文件的路径信息,f_inode记录了文件的元数据。
f_count的作用是管理文件的打开与关闭。文件IO中的open和close并不能真正的打开和关闭文件。事实上,open和close都是使f_count做加减操作,每当有程序执行open时,f_count+1;每当有程序执行close时,f_count-1。只有当f_count值为0时,文件描述符才真正被关闭。
struct path
struct path {
struct vfsmount *mnt;
struct dentry *dentry;
}
struct vfsmount:是虚拟文件系统挂载点的表示,存储有关挂载文件系统的信息。
struct dentry:目录项结构体,代表了文件系统中的一个目录项。目录项是文件系 统中的一个实体,通常对应一个文件或目录的名字。通过这个类型的属性,可以定位文件 位置。
struct inode
struct inode {
umode_t i_mode; // 文件类型和权限。这个字段指定了文件是普通文件、目录、字符设备、块设备等,以及它的访问权限(读、写、执行)。
unsigned short i_opflags;
kuid_t i_uid; // 文件的用户 ID,决定了文件的拥有者。
kgid_t i_gid; // 文件的组 ID,决定了文件的拥有者组。
unsigned int i_flags;
......
unsigned long i_ino; // inode 编号,是文件系统中文件的唯一标识。
......
loff_t i_size; // 文件大小
}
文件描述符表关联的数据结构
struct files_struct {
......
struct fdtable __rcu *fdt; // 指向当前使用的文件描述符表(fdtable)
......
unsigned int next_fd; // 存储下一个可用的最小文件描述符编号
......
struct file __rcu *fd_array[NR_OPEN_DEFAULT]; // struct file 指针的数组,大小固定,用于快速访问。
}
fdt维护了文件描述符表,其中记录了所有打开的文件描述符和 struct file的对应关系。
struct fdtable {
unsigned int max_fds; // 文件描述符数组的容量,即可用的最大文件描述符
struct file __rcu **fd; // 指向 struct file 指针数组的指针
unsigned long *close_on_exec;
unsigned long *open_fds;
unsigned long *full_fds_bits;
struct rcu_head rcu;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了