Linux下的文件描述符与文件指针

来源:互联网 发布:未成年av淘宝 编辑:IT博客网 时间:2019/06/27 19:58

文件描述符

通常说,在Linux系统中一切皆文件。当然,设备也不例外,如果要对某个设备进行操作,就不得不打开此设备文件,打开文件就会获得该文件的文件描述符fd(file discriptor),它是一个很小的整数。每个进程在PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针。
文件描述符即为文件描述符数组的下标
图中,文件描述符即为文件描述符数组的下标

文件描述符的分配规律:从当前未使用的最小的整数处开始分配
文件描述符的优点:
兼容POSIX标准,许多Linux和UNIX系统调用都依赖于它。
文件描述符的缺点:
不能移植到UNIX以外的系统上去,也不直观。

概括:
每个进程在PCB(Process Control Block)即进程控制块中都保存着一份文件描述符表,文件描述符就是这个表的索引,文件描述表中每个表项都有一个指向已打开文件的指针。现在我们明确一下:已打开的文件在内核中用file结构体表示,文件描述符表中的指针指向file结构体
(理解:fd为打开文件的文件描述符,而每个进程都有一张文件描述表,fd文件描述符就是这张表的索引,同样这张表中有一表项,该表项又是指向前面提到打开文件的file结构体,file结构体才是内核中用于描述文件属性的结构体)。

file结构体中的成员:
缓冲区基址,缓冲区当前指针,缓冲区大小,缓冲区剩余字节个数,文件读写模式等。

struct   FILE   { char   *_ptr;//文件输入的下一个位置 int    _cnt; //当前缓冲区的相对位置 char   *_base;//指基础位置(应该是文件的其始位置) int    _flag; //文件标志 int    _file; //文件的有效性验证 int    _charbuf;//检查缓冲区状况,如果无缓冲区则不读取 int    _bufsiz; //文件的大小 char   *_tmpfname;//临时文件名 }; 

文件指针

文件指针指向进程用户区中的一个被称为FILE结构的数据结构。FILE结构包括一个缓冲区和一个文件描述符。而文件描述符是文件描述符表的一个索引,因此从某种意义上说文件指针就是句柄的句柄(在Windows系统上,文件描述符被称作文件句柄)。

通常的,任何程序运行起来之后都会默认打开三个标准输入输出流:标准输入流(键盘)、标准输出 流(显示器),标准错误流(显示器)。
相应C语言的文件指针:stdin,stdout,stderror

文件描述符与文件指针的区别

简单归纳:fd只是一个整数,在open时产生。起到一个索引的作用,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp。

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

C语言的文件指针与文件描述符的相互转换

可通过fdopen和fileno两个函数实现。它们都包含在头文件stdio.h中。

fdopen的原型:

FILE * fdopen(int filedes, const char *opentype);

第一个参数filedes是一个打开的文件描述符,opentype是表示打开方式的字符串,和fopen函数具有相同的取值,比如”w”或”w+”等。但是你必须保证该字符串的描述和文件实际的打开方式是匹配的。函数fopen()就是返回打开文件的指针;如果操作失败,返回空指针null。

把文件流指针转换成文件描述符用fileno函数,
其原型为:

    int fileno(FILE *stream);

它返回和stream文件流对应的文件描述符。如果失败,返回-1。
当程序执行时,就已经有三个文件流打开了,它们分别是标准输入stdin,标准输出stdout和标准错误输出stderr。和流式文件相对应的是,也有三个文件描述符被预先打开,它们分别是0,1,2,代表标准输入、标准输出和标准错误输出。

2 1
原创粉丝点击