文件描述符&文件指针

一.文件描述符(file descriptors 简称fd)

   在linux操作系统中打开或者创建一个文件就会获得文件描述符,那仫什仫是文件描述符呢?我们知道在linux下

一切皆文件,文件描述符是OS为了高效的管理已经被打开的文件所创建的一个索引,它是一个很小的正整数,所有执

行I/O操作的系统调用都是通过文件描述符来实现的。

   我们知道一个进程的创建一定会产生对应的pcb(进程控制块),每个进程的pcb中存在文件描述符列表,文件描述

符表中的每个表项都有一个指向已经打开文件的指针,文件描述符就是这个表的索引.

   我们知道在linux系统中定义了三个常见的标准文件描述符:0(stdin代表标准输入),1(stdout标准输出),2(stderr)代表标准错误,如果此时再打开新的文件,因为0,1,2已经被占用所以新打开文件的文件描述符只能是3。

  文件描述符的分配规则:POSIX标准规定,每次打开文件时必须使用当前进程的最小可用的文件描述符号码.

   深入理解:如果我们将文件的1号文件描述符关闭,然后打开一个文件file,那仫根据上述的分配规则,这个打开文件的文件描述符就是1。看到这个你想到了什仫?此时如果我们用标准输出向显示屏上输出信息还会输出吗?下面来看一个简单的栗子:

         

       注意:文件描述符的分配数量是有范围的:0~OPEN_MAX-1

如何产生一个文件描述符

   进程获取文件描述符最常见的方法就是通过系统调用函数open和create获取,或者从父进程继承

   1).从父进程继承,那仫子进程就可以访问父进程所使用的文件。我们知道进程与进程间是互相独立的,如果有一种情况就是必须使得父子进程之间进行相互通信,此时这些父子都可以访问的文件就成了解决的突破口了

   2).open/create获取,在linux系统下用man这个命令查找该系统调用的函数

           

 

三.file结构体

        file结构体的源码可参见操作系统中的/kernels/include/linus/fs.h 中,内核维护的三种类型的文件描述符表

  1.进程级别的文件描述符表

       进程级别的文件描述符表的每一条都记录了单个文件描述符的相关信息,该表中存在如下信息:控制文件描述符操作的一组标志,对打开文件句柄的引用,这个进程级别的文件描述符列表用files_struct结构表示,在pcb中有一个该类型的指针变量files.

       file_struct的定义如下:

       

struct files_struct {
atomic_t count; /* 共享该表的进程数 */
rwlock_t file_lock; /* 保护以下的所有域,以免在tsk->alloc_lock中的嵌套*/
int max_fds; /*当前文件对象的最大数*/
int max_fdset; /*当前文件描述符的最大数*/
    int next_fd; /*已分配的文件描述符加1*/
struct file ** fd; /* 指向文件对象指针数组的指针 */
fd_set *close_on_exec; /*指向执行exec( )时需要关闭的文件描述符*/
fd_set *open_fds; /*指向打开文件描述符的指针*/
fd_set close_on_exec_init;/* 执行exec( )时需要关闭的文件描述符的初 值集合*/
        fd_set open_fds_init; /*文件描述符的初值集合*/
struct file * fd_array[32];/* 文件对象指针的初始化数组*/
};

  2).系统级别的文件描述符表

   S对所有打开的文件有一个系统级别的文件描述符列表,有的地方也叫做打开文件描述符列表,一个打开文件句柄存储了这个打开文件的全部相关信息,大概的信息如下:

          

1、当前文件偏移量 
2、打开文件时所使用的状态标识(open中的flags参数) 
3、文件访问模式(只读,只写,读写模式) 
4、与信号驱动相关的设置。 
5、对该文件的i-node引用。 
6、文件类型和访问权限。 
7、一个指针、指向该文件所持有的锁列表。 
8、文件的各种属性,包括文件大小及不同类型操作相关的时间戳。

 3).文件系统的inode表

   保存了文件系统的相关信息,这三种类型的文件描述符关系如图所示:

      

 四.与文件描述符相关的函数

open:以指定方式打开一个文件,调用成功后返回一个文件描述符。 
creat:打开一个文件,如果文件不存在则创建它,成功后返回一个文件描述符。 
close:关闭文件,进程对文件加锁全部被释放。 
read:从文件描述符对应的文件中读取文件,成功后返回读出的字节数。 
write:向文件描述符对应的文件中写入数据,成功后返回写入的字节数。 
ftruncate:把文件描述符对应的文件缩短到指定的长度。 
lseek:把文件指针设置到指定的位置,相当于库函数中的fseek。 
fsync:将已经写入到文件的数据写入到磁盘或其他下层设备中,成功返回0。 
fstat:返回文件描述符所对应文件的相关信息,把结果保存在struct stat中,成功返回0。 
fchown:修改文件描述符对应的文件的文件所有者和文件所有者组的信息。 
fchmod:修改文件描述符对应的文件的权限。 
flock:对文件施加建议性锁,成功返回0。 
fcntl:技能施加建议性锁也能施加强制性锁,能建立记录锁、读取锁,写入锁,成功返回0 
dup:复制文件描述符,返回没有使用的文件描述符中的最小编号。 
dup2:由用户指定返回的文件描述符的值,用来重新打开或重定向一个文件描述符。 
select:同时从多个文件描述符读取数据或向多个文件描述符写入数据。

   五.文件指针

    C语言中使用文件指针做I/O的句柄,文件指针指向进程用户中一个被称为FILE的结构体中,FILE结构中包含一个缓冲区和一个文件描述符,从某种意义上来说文件指针就是句柄的句柄(文件描述符也被称为文件句柄).文件指针在访问文件的时候内部是通过文件描述符实现的,上述输出重定向的栗子可证明上述观点。

    在这里就分享结束啦~~~~

       

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值