1.文件描述符是什么?
首先打开一个文件之后,为了对这个文件进行管理,就要对这个文件进行描述。当对多个文件进行管理时就需要一个文件描述信息表,这个表是一个数组结构,这个表中记录当前进程打开的所有文件的描述信息,而每个进程对应的文件描述信息表在进程的PCB中,所以如果需要操作文件,先去进程pcb中查找,而文件描述信息表的下标就可以帮助我们快速找到对应的文件描述信息,进而通过文件描述信息找到对应的文件进行操作,所以说文件描述符就是文件描述信息表的下标,是系统调用接口的操作句柄
2.文件描述符的分配规则
一个进程会默认打开三个文件描述符,分别是标准输入0、标准输出1、标准错误2,文件描述符会从最小的未分配的数字开始进行分配。
一般是从3开始分配,如果标准描述符关闭,就从0、1、2中缺失的最小的开始分配
代码演示:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
//关闭标准输出
//注释这条语句之后分配的描述符就是3
close(2);
int fd = open("tmp.txt", O_RDONLY);
printf("fd is %d\n", fd);
close(fd);
return 0;
}
运行结果:
3.文件操作重定向
1) 文件操作重定向的原理
更改文件描述符这个下标位置对应的文件描述信息数组内的描述信息,进而改变操作的文件,实现数据流向的改变
2) dup2实现重定向
函数原型:int dup2(int oldfd, int newfd);
函数功能:将newfd对应的文件信息替换为oldfd对应的文件信息,从而让newfd也指向oldfd对应的文件
参数:
oldfd:要更改的文件描述符
newfd:重定向的文件描述符
返回值:成功返回newfd,失败返回-1
代码演示:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
umask(0);
int fd = open("tmp.txt", O_WRONLY | O_CREAT, 0664);
if(fd < 0)
{
perror("open error");
exit(-1);
}
//让fd描述符复制标准输出下标对应的的文件描述信息,fd也操作标准输出对应的文件
int ret = dup2(1, fd);
char* str = "重定向测试\n";
int len = strlen(str);
//将数据写入fd对应的文件
write(fd, str, sizeof(char) * len);
//打印dup2的返回值
printf("ret = %d\n", ret);
close(fd);
return 0;
}
运行结果:
4.文件描述符和文件流指针的关系
文件描述符是系统调用的操作句柄,文件流指针是库函数的操作句柄,文件流指针通过封装文件描述符,进而操作文件