【Linux操作系统】简学深悟启示录:文件fd

1.前言

有些东西作为共识原理,我们都要知道,知道我们学习文件到底是在学什么?

  • 文件 = 内容 + 属性
  • 文件分为打开的文件和没打开的文件
  • 已打开的文件本质就是在研究文件和进程的关系
  • 没打开的文件一般存放在磁盘上,我们最关心什么问题?系统是怎么管理文件的?如何先描述再组织的?重定向和缓冲区的本质?

2.C文件接口回顾

在这里插入图片描述

以上代码将会对 C 文件相关的函数使用细节进行回顾,但是具体的函数使用就不回顾了,可自行查询学习

fopen 以写方式打开 log.txt 文件,fwritestr 写入 fp 文件,注意会以二进制写入,所以要符合字符编码,尽量以字符串写入,最后 fclose 关闭文件。运行代码可以发现确实多了一个 log.txt 的文件,该文件创建在与代码编译文件同一目录下,这是默认路径的结果,有没有什么办法改变默认路径呢?

chdir(/home/zzh_test);

chdir 是一种用于修改当前进程工作目录的函数,将这一行代码添加到 main 函数最前面,然后要在 fwrite 后加个 sleep(1000) 用于暂停观察进程状态,还要加个 fflush(fp) 刷新缓冲区(原因后面会讲)

在这里插入图片描述

可以看到文件的路径确实被修改了,能够在 /home/zzh_test 路径下被找到

我们修改 fwrite 之后再次打开文件发现之前内容消失了,这是因为 w 方式打开的文件会清空文件,想要添加内容应该用 a 方式打开

还有很多 C 文件函数就不赘述了~

3.stdin & stdout & stderr

在系统中有三个输入输出流会被默认打开,分别是 stdin (键盘输入)、stdout (显示器输出)、stderr (显示器输出错误信息)

在这里插入图片描述

这三个输入输出流分别对应 012 的文件描述符,文件描述符可以理解为一种问津标签,这三个输入输出流分别独立互不影响

例如 fprintf(stdout,"hello world") 表示向显示器打印,等价于 printf("hello world")

4.系统文件调用

文件是存在于磁盘上的,访问文件就是访问磁盘,也就是访问硬件,也就是通过代码访问硬件,必定是要经过操作系统的接口的。我们所学的 C 文件函数其实都是封装了系统文件的

在这里插入图片描述

4.1 open

在这里插入图片描述

我们这里介绍下面这条函数:

pathname:要打开或创建的目标文件
flags:打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行 或运算 构成 flags

#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define ONE (1<<0) // 1
#define TWO (1<<1) // 2
#define THREE (1<<2) // 4
#define FOUR (1<<3) // 8

void show(int flags)
{
    if(flags&ONE) printf("hello function1\n");
    if(flags&TWO) printf("hello function2\n");
    if(flags&THREE) printf("hello function3\n");
    if(flags&FOUR) printf("hello function4\n");
}

int main()
{
    show(ONE);
    show(TWO);
    show(ONE|TWO);
    show(ONE|TWO|THREE);
    return 0;
}

系统里对于 flags 多个选项组合使用多个功能又互不影响,使用的是以上类似的代码

如果 flagsONE | TWO(0001 | 0010 = 0011),那么 flags & ONE(0011 & 0001 = 0001)flags & TWO(0011 & 0010 = 0010)都会非 0,所以会同时打印 hello function1hello function2

flags 参数:

  • 打开方式标志(必选其一,且只能选一个),常用取值:
    O_RDONLY:只读模式
    O_WRONLY:只写模式
    O_RDWR:读写模式
  • 可组合的附加标志(用 | 连接):
    O_CREAT:若文件不存在则创建
    O_TRUNC:打开文件时清空原有内容
    O_APPEND:追加模式(写入内容到文件末尾)
    O_EXCL:与 O_CREAT 一起使用,若文件已存在则报错

mode:当使用 O_CREAT 时,需指定新文件的权限(如 0644),否则可省略

返回值: 文件描述符

4.2 write

在这里插入图片描述

write 的使用和 fwrite 差不多,不过是把目标文件改成文件描述符,返回的是写入的字符个数

使用示例如下:

在这里插入图片描述

5.访问文件本质

0

上面我们多次提到文件描述符,这到底是什么?又有什么用呢?

内存中的 PCB,即 task_struct,内部有个 struct files_struct* files 指针,指向一个 struct files_struct 结构体,里面包含了一个 struct file *fd_array[],这个数组就叫文件描述符表,该数组的每个下标就是一个 fd,存储了各个文件存储的地址,fd 相当于文件的标志,这些文件通常是 struct file,描述了一个被打开文件的信息

在这里插入图片描述

🔥值得注意的是

  • struct file 中文件描述符为 fileno
  • FILE 的本质就是封装了 fd 的结果
  • 文件会尽量往文件描述符表低位存储,即使 stdout 关闭显示器输出,也不会影响 stderr,因为他们两是独立开来的

希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

请添加图片描述

评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值