最近重读APUE,之前很多一知半解的概念变得清晰了许多。其中就有关于Linux文件操作的一些系列api及其背后的概念。刚好就在博客里总结一下。
本文仅针对一般文件的操作,由于Linux“一切皆文件”的设计哲学,如果要谈广义上的文件操作,那么socket编程相关的内容也要牵扯进来了。
首先,Linux对进程提供文件描述符(file descriptor,以下简称fd)作为所有文件的身份标示。对于每个进程而言,在进程用户空间维护一张文件描述符表。表的每一行包含两项--文件描述符及文件指针。文件指针指向打开文件表(open file table)的一行.打开文件表是一张系统级的表。每一行包括了文件偏移量,文件状态(status flag),以及一个指向inode表项的指针,inode表同样是一张系统级的表,它储存了真正的被打开文件的文件信息,文件锁等数据,其每一项与实际打开文件是一对一的关系。
打开文件表和实际打开文件的关系是多对一的关系。这是由于同一个文件会被以不同的形式(r/w/rw)打开多次,也会被多个进程打开多次。每一次open操作都会创建一个文件描述符表项和打开文件表项。同时,由于子进程对父进程文件表的继承,以及dup操作导致的文件别名现象,文件描述符项与打开文件表项也是多对一关系。
文件描述符表,打开文件表,inode表关系如下图所示