文件描述符与文件指针

文件描述符(fd)

文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。

什么是文件描述符?

进程利用文件描述符来访问文件。文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,进程就返回一个文件描述符。

每个linux进程都应该有三个标准的文件描述符,对应三个标准流。
fd(0)对应标准输入(stdin),对应的设备键盘(文件)。
fd(1)对应标准输出(stdout),对应的设备显示器(文件)。
fd(2)对应标准错误(stderror),对应的设备显示器(文件)。

文件描述符的分配是从当前未被使用的最小值分配。(如:再创建文件时,对应的fd为3,依次类推。如果关闭了0(close(0);)下一个打开文件的文件描述符为1)

在Linux中,每个进程会在进程控制块(task_struct)当中保存着一份文件描述符表,文件描述符就是这个表的索引,每个表都有一个指向已经打开文件的指针。
这里写图片描述


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

什么是文件指针?

在C语言中,一个指针变量指向一个文件,则这个指针就是文件指针。文件指针指向进程用户区中的一个被称为FILE结构的数据结构。

文件描述符是唯一的,但是文件指针不是唯一的,文件指针指向的对象是唯一的。文件描述符是文件描述符表的一个索引,因此从某些意义上来说,文件指针就是文件描述符的句柄。


FILE结构包含的字段及内容

C语言的stdio.h头文件中,定义了用于文件操作的结构体FILE

#define NULL 0
#define EOF (-1)
#define BUFSIZ 1024
#define OPEN_MAX 20  // 一次打开的最大文件数

// 定义FILE结构体
typedef struct _iobuf {
    int cnt;  // 剩余的字符,如果是输入缓冲区,那么就表示缓冲区中还有多少个字符未被读取
    char *ptr;  // 下一个要被读取的字符的地址
    char *base;  // 缓冲区基地址
    int flag;  // 读写状态标志位
    int fd;  // 文件描述符
} FILE;

extern FILE _iob[OPEN_MAX];

#define stdin (&_iob[0])  // stdin 的文件描述符为0
#define stdout (&_iob[1])  // stdout 的文件描述符为1
#define stderr (&_iob[2])  // stdout 的文件描述符为2

enum _flags {
    _READ =01,  // 读文件
    _WRITE =02,  // 写文件
    _UNBUF =04,  // 无缓冲
    _EOF = 010,  // 文件结尾EOF
    _ERR = 020  // 出错
};

int _fillbuf(FILE *);  // 函数声明,填充缓冲区
int _flushbuf(int, FILE *);  // 函数声明,刷新缓冲区

#define feof(p) ((p)->flag & _EOF) != 0)
#define ferror(p) ((p)->flag & _ERR) != 0)
#define fileno(p) ((p)->fd)
#define getc(p) (--(p)->cnt >= 0 \
    ? (unsigned char) *(p)->ptr++ : _fillbuf(p))
#define putc(x,p) (--(p)->cnt >= 0 \
    ? *(p)->ptr++ = (x) : _flushbuf((x),p))
#define getchar() getc(stdin)
#define putcher(x) putc ((x), stdout)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值