Linux系统编程5_文件描述符
linux把一切都当作文件,包括设备;我们的显示器和键盘在linux系统来说都是文件;
简单来理解:一个 Linux 进程可以打开成百上千个文件,为了表示和区分已经打开的文件,Linux 会给每个文件分配一个编号(一个 ID),这个编号就是一个整数,被称为文件描述符(File Descriptor)。
一个 Linux 进程启动后,会在内核空间中创建一个 PCB 控制块,PCB 内部有一个文件描述符表(File descriptor table),记录着当前进程所有可用的文件描述符,也即当前进程所有打开的文件。
除了文件描述符表,系统还需要维护另外两张表:
打开文件表(Open file table)
i-node 表(i-node table)
文件描述符表每个进程都有一个,打开文件表和 i-node 表整个系统只有一个。三者关系如下:
文件描述符实际就是每个进程的文件描述符表的索引;通过索引(文件描述符)可以快速得到一个文件指针。
这个文件指针实际上打开文件表的索引,通过打开文件表的索引(文件指针),可以得到文件的三个重要信息:
- 文件偏移量,也就是文件内部指针偏移量。调用 read() 或者 write() 函数时,文件偏移量会自动更新,当然也可以使用 lseek() 直接修改。
- 状态标志,比如只读模式、读写模式、追加模式、覆盖模式等。
- i-node 表指针。
真正要读写文件,还是得通过i-node表指针(i-node表的索引),也可以理解成inode号码。得到inode信息,这是文件的元信息:
- 文件的字节数
- 文件拥有者的User ID
- 文件的Group ID
- 文件的读、写、执行权限
- 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
- 链接数,即有多少文件名指向这个inode
- 文件数据block的位置
用户通过文件名,打开文件。
实际上,系统内部这个过程分成三步:
首先,系统找到这个文件名对应的inode号码;
其次,通过inode号码,获取inode信息;
最后,根据inode信息,找到文件数据所在的block,读出数据。
另外对于文件描述符的理解:
同一个进程的不同文件描述符可以指向同一个文件;
不同进程可以拥有相同的文件描述符;
不同进程的同一个文件描述符可以指向不同的文件(一般也是这样,除了 0、1、2 这三个特殊的文件);
不同进程的不同文件描述符也可以指向同一个文件。
接下来总结一下文件的类型:
普通文件类型:Linux中最多的一种文件类型, 包括 纯文本文件(ASCII);二进制文件(binary);数据格式的文件(data);各种压缩文件.第一个属性为 [-]
目录文件:就是目录, 能用 # cd 命令进入的。第一个属性为 [d],例如 [drwxrwxrwx]
块设备文件:就是存储数据以供系统存取的接口设备,简单而言就是硬盘。例如一号硬盘的代码是 /dev/hda1等文件。第一个属性为 [b]
字符设备文件:即串行端口的接口设备,例如键盘、鼠标等等。第一个属性为 [c]
套接字文件:这类文件通常用在网络数据连接。可以启动一个程序来监听客户端的要求,客户端就可以通过套接字来进行数据通信。第一个属性为 [s],最常在 /var/run目录中看到这种文件类型
管道文件:FIFO也是一种特殊的文件类型,它主要的目的是,解决多个程序同时存取一个文件所造成的错误。FIFO是first-in-first-out(先进先出)的缩写。第一个属性为 [p]
链接文件:类似Windows下面的快捷方式。第一个属性为 [l],例如 [lrwxrwxrwx]
参考链接:
Linux文件描述符到底是什么?:http://c.biancheng.net/view/3066.html
linux文件描述符详解:https://www.cnblogs.com/alan666/p/8311890.html
linux文件管理:https://blog.csdn.net/wwwlyj123321/article/details/100298377
Linux系统中inode和block详解:https://www.cnblogs.com/yunxuanedu/p/13915421.html