Linux文件描述符相关知识
文件描述符与内核数据结构
什么是文件描述符(File Descriptor)
-
在 Linux 中,打开或创建文件/套接字时,操作系统会返回一个非负整数,这个数就是文件描述符(简称 FD)。
-
它相当于是程序访问文件或资源的“凭证”或“句柄”。
🧷 常见文件描述符编号
FD编号 | 含义 | 名称 |
---|---|---|
0 | 标准输入 | stdin |
1 | 标准输出 | stdout |
2 | 标准错误输出 | stderr |
文件描述符背后的内核数据结构
当我们打开文件时,系统会创建/维护一系列内核数据结构,下面来简单了解这些结构及其作用。
struct file
— 文件对象
每个 FD 都指向一个
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; // 特定驱动或模块的私有数据
};
struct path
— 路径结构
struct path {struct vfsmount *mnt; // 文件系统挂载点struct dentry *dentry; // 目录项,表示文件名
};
用于定位文件在文件系统中的路径。
struct inode
— 文件元信息
每个文件在磁盘上都有一个唯一的 inode,记录它的元信息(但不含文件名)
struct inode {umode_t i_mode; // 文件类型 + 权限(读写等)kuid_t i_uid; // 所有者的用户 IDkgid_t i_gid; // 所属组的组 IDunsigned long i_ino; // inode 编号(唯一标识)loff_t i_size; // 文件大小(单位:字节)
};
进程如何管理文件描述符?
每个进程都维护一个自己的“打开文件表”,用来记录它打开的所有文件。
struct files_struct
— 打开文件列表
struct files_struct {struct fdtable *fdt; // 指向文件描述符表unsigned int next_fd; // 下一个可用的文件描述符struct file *fd_array[]; // file结构体数组(最多同时打开多少个文件)
};
struct fdtable
— 文件描述符表
struct fdtable {unsigned int max_fds; // 最大支持的文件描述符数量struct file **fd; // file 指针数组unsigned long *open_fds; // 打开状态位图
};
文件描述符就是
fd
数组中的下标。
举个例子:文件描述符是怎么工作的?
-
调用
open("a.txt", O_RDONLY);
-
内核会:
-
创建一个
struct file
,记录这个文件的各种信息; -
在当前进程的
files_struct
中分配一个空位(比如编号是 3); -
将这个
struct file
关联到fd[3]
; -
返回这个文件描述符(3)给用户程序。
-
所以:
文件描述符 = 文件操作能力的“钥匙”
本质上就是struct file
的一个“引用号”
5️ 总结
文件描述符是程序访问文件等资源的数字“句柄”,它背后链接的是内核中记录文件信息的
struct file
结构。通过它,程序可以对文件进行读、写等操作,而不需要直接管理底层资源。