文章参考:文件描述符的本质文件描述符和文件指针的区别文件描述符fd和文件指针flip的理解

推荐:task_struct 和文件系统的关系

系统中文件相关表

  右侧的表称为i节点表,在整个系统中只有1张。该表可以视为结构体数组,该数组的一个元素对应于一个物理文件。

  中间的表称为文件表,在整个系统中只有1张。该表可以视为结构体数组,一个结构体中有很多字段,其中有3个字段比较重要:

    file status flags:用于记录文件被打开来读的,还是写的。其实记录的就是open调用中用户指定的第2个参数
    current file offset:用于记录文件的当前读写位置(指针)。正是由于此字段的存在,使得一个文件被打开并读取后,下一次读取将从上一次读取的字符后开始读取
    v-node ptr:该字段是指针,指向右侧表的一个元素,从而关联了物理文件。

  左侧的表称为文件描述符表,每个进程有且仅有1张。该表可以视为指针数组,数组的元素指向文件表的一个元素。最重要的是:数组元素的下标就是大名鼎鼎的文件描述符,数组元素的值就是指向 File 结构体的指针

系统调用时的操作

  文件描述符的操作函数 open, 返回一个文件描述符,内核会在每个进程空间中维护一个文件描述符表,所有打开的文件都将通过此表中的文件描述符来引用。

    新建一个i节点表元素,让其对应打开的物理文件(如果对应于该物理文件的i节点元素已经建立,就不做任何操作);

    新建一个文件表的元素,根据open的第2个参数设置file status flags字段,将current file offset字段置0,将v-node ptr指向刚建立的i节点表元素;

    在文件描述符表中,寻找1个尚未使用的元素,在该元素中填入一个指针值,让其指向刚建立的文件表元素。最重要的是:将该元素的下标作为open的返回值返回。

  文件描述符的操作函数 read(write,)根据传入的文件描述符,OS就可以找到对应的文件描述符表元素,进而找到文件表的元素,进而找到i节点表元素,从而完成对物理文件的读写。

  而流操作函数 fopen, 返回的是一个FILE结构指针,FILE结构是包含有文件描述符的,FILE结构函数可以看作是对fd直接操作的系统调用的封装,它的优点是带有I/O缓存。

文件描述符和文件指针的概念一总

  文件描述符:在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。每个进程在PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。即已打开的文件在内核中用 File 结构体表示,文件描述符表中的指针指向 File 结构体。优点是兼容POSIX标准,许多系统调用都依赖于它;缺点是不能移植到unix之外的系统上去。

  文件指针:C语言中使用文件指针而不是文件描述符做为I/O的句柄。文件指针指向进程用户区中的一个被称为FILE结构的数据结构。FILE结构主要包括一个I/O缓冲区和一个文件描述符。而文件描述符是文件描述符表中的一个索引,因此从某种意义上说文件指针就是句柄的句柄(在Windows系统上,文件描述符被称作文件句柄)。相当于在上图中最左侧又虚拟出一个 struct File,其中 struct 中有个元素是文件描述符,指向进程表项中的 fd 索引(自己的理解,不知道正不正确)。文件指针的优点是C语言中的通用格式,便于移植。

  既然FILE结构中含有文件描述符,那么可以使用fopen来获得文件指针,然后从文件指针获取文件描述符,文件描述符应该是唯一的,而文件指针却不是唯一的,但指向的对象是唯一的

进程与文件描述符

  内核会在每个进程空间中维护一个文件描述符表, 所有打开的文件都将通过此表中的文件描述符来引用; 而流(如: fopen)返回的是一个FILE结构指针, FILE结构是包含有文件描述符的,FILE结构函数可以看作是对fd直接操作的系统调用的封装, 它的优点是带有I/O 缓存。

  每个进程在PCB(Process Control Block)即进程控制块中都保存着一份文件描述符表,文件描述符就是这个表的索引,文件描述表中每个表项都有一个指向已打开文件的指针,现在我们明确一下:已打开的文件在内核中用 FILE 结构体表示,文件描述符表中的指针指向 FILE 结构体。

fork 对文件描述符的影响

  fork会导致子进程继承父进程打开的文件描述符,其本质是将父进程的整个文件描述符表复制一份,放到子进程的PCB中。因此父、子进程中相同文件描述符(文件描述符为整数)指向的是同一个文件表元素,这将导致父(子)进程读取文件后,子(父)进程将读取同一文件的后续内容。所以在创建守护进程时,都使用 close 关闭掉从父进程继承的文件描述符。

FILE的结构

struct _iobuf {
  char *_ptr; //缓冲区当前指针
  int _cnt; //文件的引用计数
  char *_base; //缓冲区基址
  int _flag; //文件读写模式
  int _file; //文件描述符
  int _charbuf; //缓冲区剩余自己个数
  int _bufsiz; //缓冲区大小
  char *_tmpfname;
};
typedef struct _iobuf FILE;

open和fopen的区别

  open:返回一个文件描述符,无缓冲,与 write、read 配合使用

  fopen:返回 File *,有缓冲,与 fwrite、fread 配合使用

Linux-文件描述符的本质及与文件指针的区别的更多相关文章

  1. Linux 利用进程打开的文件描述符(/proc)恢复被误删文件

    Linux 利用进程打开的文件描述符(/proc)恢复被误删文件 在 windows 上删除文件时,如果文件还在使用中,会提示一个错误:但是在 linux 上删除文件时,无论文件是否在使用中,甚至是还 ...

  2. 文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换(转)

    转自: http://blog.csdn.net/jenghau/article/details/5532265 文件指针/句柄(FILE*).文件描述符(fd)以及 文件路径(filepath)的相 ...

  3. linux文件描述符open file descriptors与open files的区别

    一个文件被打开,也可能没有文件描述符,比如current working diretories,memory mapped files and executable text files ;losf可 ...

  4. linux专题一之文件描述符、重定向、管道符、tee命令

    本节讨论一下几个问题: 1. 文件描述符. 2. 重定向. 3. 管道符 4. tee的用法. 1. 文件描述符. 在linux系统中一切皆文件.文件夹和设备都是文件.如何用来区别不同的文件呢?这里的 ...

  5. Linux文件描述符与打开文件之间的区别(转载)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239   1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为: ...

  6. linux文件描述符--转载

    转自:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录 ...

  7. Linux中的文件描述符与打开文件之间的关系

    Linux中的文件描述符与打开文件之间的关系 导读 内核(kernel)利用文件描述符(file descriptor)来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描 ...

  8. Linux中的文件描述符与打开文件之间的关系------------每天进步一点点系列

    http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件. ...

  9. (转)Linux中的文件描述符

    本文转自:http://blog.csdn.net/cywosp/article/details/38965239 作者:cywosp 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为 ...

随机推荐

  1. ***LANMP镜像手册(Apache&Nginx)-lanmp-oneinstack

    LANMP镜像手册(Apache&Nginx) Version PHP7.0.26  转自:http://docs.websoft9.com/xdocs/lanmp-oneinstack-im ...

  2. [HNOI2016]序列(未通过)

    题解: 虽然知道有点问题但是并没有debug出来 发现错误了..相同元素的处理有错误 网上题解大都是分块..(hn怎么道道分块) 用最普通的思路,可以枚举每个点作为最小值,向左向右延伸 但是多组询问显 ...

  3. Codeforces 707E Garlands

    Garlands 我怎么感觉好水啊. 因为询问只有2000组, 离线询问, 枚举联通块再枚举询问, 二维树状数组更新答案. #include<bits/stdc++.h> #define ...

  4. 一种使用pyinstaller时图标问题解决方案

    一种使用pyinstaller时图标问题解决方案 0x00 场景   使用pyinstaller将.py文件编译成.exe文件时,想要使用自己心仪的图标(.ico)比较麻烦.在使用pyinstalle ...

  5. Burp Suite之爬网模块(二)

    Spider功能 Burp Spider爬网介绍 Burp Spider 是一个映射 web 应用程序的工具.它使用多种智能技术对一个应用程序的内容和功能进行全面的清查. 通过跟踪 HTML 和 Ja ...

  6. 005.HAProxy+Keepalived高可用负载均衡

    一 基础准备 1.1 部署环境及说明 系统OS:CentOS 6.8 64位 HAProxy软件:HA-Proxy version 1.5.18 Keepalived软件:keepalived-1.3 ...

  7. Linux虚拟机上安装redis

    1.检查安装依赖程序 yum install gcc-c++ yum install -y tcl yum install wget 2.获取安装文件 wget http://download.red ...

  8. 2827: 千山鸟飞绝 非旋treap

    国际惯例的题面:看起来很不可做的样子,我们先来整理一下题意吧.就是,维护每个点曾经拥有过的最大的两个属性值,支持把点的位置移动.我们用map对每个位置进行离散化,对每个位置建立一个平衡树.为了方便分离 ...

  9. cf348D. Turtles(LGV定理 dp)

    题意 题目链接 在\(n \times m\)有坏点的矩形中找出两条从起点到终点的不相交路径的方案数 Sol Lindström–Gessel–Viennot lemma的裸题? 这个定理是说点集\( ...

  10. 洛谷.2234.[HNOI2002]营业额统计(Splay)

    题目链接 //模板吧 #include<cstdio> #include<cctype> #include<algorithm> using namespace s ...