文章目录
1.前言
有些东西作为共识原理,我们都要知道,知道我们学习文件到底是在学什么?
- 文件 = 内容 + 属性
- 文件分为打开的文件和没打开的文件
- 已打开的文件本质就是在研究文件和进程的关系
- 没打开的文件一般存放在磁盘上,我们最关心什么问题?系统是怎么管理文件的?如何先描述再组织的?重定向和缓冲区的本质?
2.C文件接口回顾

以上代码将会对 C 文件相关的函数使用细节进行回顾,但是具体的函数使用就不回顾了,可自行查询学习
fopen 以写方式打开 log.txt 文件,fwrite 将 str 写入 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 (显示器输出错误信息)

这三个输入输出流分别对应 0、1、2 的文件描述符,文件描述符可以理解为一种问津标签,这三个输入输出流分别独立互不影响
例如 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 多个选项组合使用多个功能又互不影响,使用的是以上类似的代码
如果 flags 是 ONE | TWO(0001 | 0010 = 0011),那么 flags & ONE(0011 & 0001 = 0001)和 flags & TWO(0011 & 0010 = 0010)都会非 0,所以会同时打印 hello function1 和 hello 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.访问文件本质

上面我们多次提到文件描述符,这到底是什么?又有什么用呢?
内存中的 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,因为他们两是独立开来的
希望读者们多多三连支持
小编会继续更新
你们的鼓励就是我前进的动力!

1611

被折叠的 条评论
为什么被折叠?



