文件描述符fd
文件描述符就是一个小的正整数,是内核中文件描述信息结构体数组的下标,对应有一个文件描述信息来操作文件
当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进 程和文件关联起来。每个进程都有一个指针files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数 组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件 描述符,就可以找到对应的文件
struct files_struct里面包含了结构体指针数组struct file[ ],数组中存放的是指向struct file的地址,通过找到struct file就可以找到文件
文件描述符的分配规则- - - 最小未使用
文件描述符和文件流指针的关系
文件描述符可以直接操作文件,但是不方便,所以封装接口,增加功能,变成了文件流指针
同库函数与系统调用接口一样,库函数可以看作是对系统调用接口的封装
库函数操作的是文件流指针(FILE*类型的结构体指针数组)
系统调用接口操作的是文件描述符(int 类型的整数)
重定向
重定向指的是文件描述符的重定向;如果文件描述符这个下标的文件描述信息从一个文件变成了另一个文件,当用户通过文件描述符向文件写入数据时,数据就因为描述符信息的改变而流向另一个文件
简单来说,就是讲要写入文件A的数据写入到另一个文件
两种重定向
>> 追加重定向 即 O_APPEND
> 清空重定向 即 O_TRUNC
dup
dup的主要功能是将oldfd对应的描述信息拷贝一份到newfd,新旧文件描述符都指向同一个文件,这里主要说明常用的dup2
int dup2(int oldfd,int newfd); 让newfd重定向到oldfd
功能:将oldfd描述符对应的描述信息向newfd拷贝一份
让newfd也指向oldfd所指向的文件
若newfd本身已经有打开的文件,则关闭这个文件
fd=open(./test.txt);
dup2(fd,1); 把1重定向到fd所指向的文件,1也指向test.txt这个文件
fd=open(./test.txt,O_APPEND);
dup2(fd,1); 把1重定向到fd所指向的文件,再次写入时写到文件最后
用户态缓冲区
先看代码
printf("hello world"); //库函数
fprintf("hello world"); //系统调用接口
printf打印的数据不会立即被写入到标准输出文件中,而是先将数据写入到一块缓冲区中,等到缓冲区写满或者用户手动刷新缓冲区fflush,才会将数据一次性写入文件中;
我们通常所说的缓冲区值得就是文件流指针中描述的缓冲区,系统调用是没有这个缓冲区的,这个缓冲区通常也被称为用户态缓冲区