文件描述符就是内核中 struct file* fd_array[]
数组的下标,进程可以通过这个下标找到文件的描述信息,进而操作文件。
#include
#include
#include
#include
#include
int main() {
char buf[1024];
ssize_t s = read(0, buf, sizeof(buf));
if(s > 0){
buf[s] = 0;
write(1, buf, strlen(buf));
write(2, buf, strlen(buf));
}
return 0;
}
pcb ->files_struct ->fd_arry[]
而现在知道,文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件
最小未使用
代码示例:
#include
#include
#include
#include
int main() {
int fd = open("myfile", O_RDONLY);
if(fd < 0){
perror("open err");
return 1;
}
printf("fd: %d\n", fd);
close(fd);
return 0;
}
输出发现是 fd: 3
关闭0或者2,在看
#include
#include
#include
#include
int main() {
close(0);
//close(2);
int fd = open("myfile", O_RDONLY);
if(fd < 0){
perror("open");
return 1;
}
printf("fd: %d\n", fd);
close(fd);
return 0;
}
发现是结果是: fd: 0 或者 fd: 2
文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。
注意:
文件描述符实际是有限的,若不关闭文件,文件描述符被用光了,就打不开新文件了
文件描述符:是一个非负整数
文件流指针:FILE结构体 - - typedef struct _IO_FILE FILE
文件流指针是库函数IO接口的操作句柄
文件描述符是系统调用IO接口的操作句柄
文件流指针这个结构体中封装了文件描述符
通过文件流指针进行最终文件操作的时候,依然还要能够找到文件对应的文件描述符才可以
文件流指针是一个结构体,结构体中有很多成员变量,其中就有一个叫 _fileno (这是文件描述符)
那如果关闭1呢?看代码:
#include
#include
#include
#include
#include
int main() {
close(1);
int fd = open("myfile", O_WRONLY|O_CREAT, 00644);
if(fd < 0){
perror("open err");
return 1;
}
printf("fd: %d\n", fd);
fflush(stdout);
close(fd);
exit(0);
}
此时,我们发现,本来应该输出到显示器上的内容,输出到了文件 myfile
当中,其中,fd=1
。这种现象叫做输出重定向。
有:> (清空重定向);>> (追加重定向)
符号 | 作用 |
---|---|
命令 > 文件 | 将标准输出重定向到文件中(清除原有文件中的数据) |
命令 >> 文件 | 将标准输出重定向到文件中(在原有的内容后追加) |
针对文件描述符所对应的文件描述信息的重定向:
操作的文件描述符/文件流指针并没有改变,但是实际操作的文件却改变了
实现方式就是替换这个描述符对应的文件描述信息
实际是描述符的重定向,改变描述符所指向的文件,就改变了数据的流向
int dup2(int oldfd, int newfd); - 描述符重定向函数
第一行 >/dev/null , 2>&1 这两个重定向交换位置的意义不同!
答案:系统调用接口,异常,中断
A 标准输出重定向到标准错误输出
B 标准输入重定向到标准错误输出
C 标准输出重定向到标准输入
D 标准错误输出重定向到标准输入
正确答案: A
答案解析:
0 ,1,2叫文件描述符;Linux中,每打开一个文件都有一个小的整数与之对应,就是文件描述符!
0 是标准输入的 (stdin)
1 是标准输出的 (stdout)
2 是标准报错输出的 (stderr)
'<'是输入重定向符
‘>’是输出重定向符
看到这里啦,动动小手留个赞呐!