File descriptor(FD)

Contains:
1、FD
2、fcntl
3、dup、dup2    
4、ioctl
文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。

引用
文件描述符在形式上是一个非负整数。
     实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。


优点:
文件描述符的优点主要有两个:
   * 基于文件描述符的I/O操作兼容POSIX标准。
   * 在UNIX、Linux的系统调用中,大量的系统调用都是依赖于文件描述符。
FD的生成
   * open(), open64(), creat(), creat64()
   * socket()
   * socketpair()
   * pipe()

对于内核而言,所有打开的文件都通过文件描述符引用。
内核使用三种数据结构表示打开的文件,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。
1、每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:
  • a、文件描述符标志(close_on_exec)
  • b、指向文件表项的指针

2、内核为所有打开文件维持一张文件表。每个文件表项包含:
  • a、文件状态标志(读、写、添写、同步和非阻塞等)
  • b、当前文件偏移量
  • c、指向该文件v节点表项的指针

3、每个打开文件都有一个v节点结构,v节点包含了文件类型和对此文件进行各种操作的函数的指针。对于大多数文件,v节点还包含了该文件的i节点。

关于多个进程同时写同一文件的时候,会产生覆盖的问题,unix提供了一种方法使这个操作成为原子操作,该方法是打开文件时设置O_APPEND标志。每次对文件进行写之前,都将进程的当前偏移量设置到该文件的尾端处,于是在每次写之前就不再需要调用lseek。

dup和dup2

用来复制一个现存的文件描述符
#include <unistd.h>
int dup(int fieldes)
int dup2(int fieldes, int fieldes2)

dup返回的新文件描述符一定是当前可用的文件描述符中的最小数值。dup2的fieldes2参数可以制定新描述符的数值。如果fieldes2已经打开,则将其先关闭。
返回的新文件描述符与参数fieldes共享一个文件表项。
复制一个描述符的另外一种方法是使用fcntl
dup(fieldes); 等效于fcntl(fieldes, F_DUPFD, 0);
dup2(filedes, fieldes2);等效于
close(fieldes2);
fcntl(fieldes,F_DUPFD, filedes2)
fcntl函数

可以改变已经打开文件的性质。
#include <fcntl.h>
int fcntl(int fieldes. int cmd, .../* int arg */);

它提供了五种功能:
  • 1、复制一个现有的描述符(cmd = F_DUPFD).
  • 2、获得/设置文件描述符标记(cmd = F_SETFD 或 F_GETFD)
  • 3、获得/设置文件状态标志(cmd = F_GETFL 或 F_SETFL)
  • 4、获得/设置异步I/O所有权(cmd = F_GETOWN或 F_SETOWN )
  • 5、获得/设置纪录锁(cmd =  F_GETLK、F_SETLK或者F_SETLKW)

ioctl函数
ioctl函数是I/O操作的杂物箱。
dev/fd
较新的系统都提供名为/dev/fd的目录,其目录项是名为0、1、2等的文件。打开文件/dev/fd/n等效于复制描述符n

参考资料:
http://en.wikipedia.org/wiki/File_descriptor
http://zh.wikipedia.org/wiki/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6

猜你喜欢

转载自2057.iteye.com/blog/1830325