file descriptor(以下简称fd)又叫文件描述符,他是一个抽象的指示符,用一个整数表示(非负整数)。它指向了由系统内核维护的一个file table中的某个条目(entry)。这个解释可能过于抽象,不过在正式详细介绍fd之前,有必要先了解用户程序和系统内核之间的工作过程。 注: 本文描述的所有场景仅限于类unix系统环境,在windows中这玩意叫file handle(臭名昭著的翻译: 句柄)。 现代操作系统会把内存划分为2个区域,分别为Use space(用户空间) 和 Kernel space(内核空间)。用户的程序在User space执行,系统内核在Kernel space中执行。 用户的程序没有权限直接访问硬件资源,但系统内核可以。比如读写本地文件需要访问磁盘,创建socket需要网卡等。因此用户程序想要读写文件,必须要向内核发起读写请求,这个过程叫system call。 内核收到用户程序system call时,负责访问硬件,并把结果返回给程序。 上面简单介绍了User space和Kernel space,这对于理解fd有很大的帮助。fd会存在,就是因为用户程序无法直接访问硬件,因此当程序向内核发起system call打开一个文件时,在用户进程中必须有一个东西标识着打开的文件,这个东西就是fd。 和fd相关的一共有3张表,分别是file descriptor、file table、inode table,如下图所示。 另外,每个进程都会预留3个默认的fd: stdin、stdout、stderr;它们的值分别是0、1,2。 当程序向内核发起system call open(),内核将会User space & Kernel space
File Descriptor
file tables

file descriptors table由用户进程所有,每个进程都有一个这样的表,这里记录了进程打开的文件所代表的fd,fd的值映射到file table中的条目(entry)。
file table是全局唯一的表,由系统内核维护。这个表记录了所有进程打开的文件的状态(是否可读、可写等状态),同时它也映射到inode table中的entry。
inode table同样是全局唯一的,它指向了真正的文件地址(磁盘中的位置),每个entry全局唯一。流程
当程序再次发起read()system call时,需要把相关的fd传给内核,内核定位到具体的文件(fd –> file table –> inode table)向磁盘发起读取请求,再把读取到的数据返回给程序处理参考链接